问题标签 [table-locking]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3144 浏览

mysql - 带表锁定的Mysql事务

我需要使用表锁定(写入)并同时更新一些表,因此我需要同时进行事务,因为锁定不是事务安全的。

从 mysql 文档中,我阅读了以下 https://dev.mysql.com/doc/refman/5.6/en/lock-tables-and-transactions.html

将 LOCK TABLES 和 UNLOCK TABLES 与事务表(例如 InnoDB 表)一起使用的正确方法是使用 SET autocommit = 0(不是 START TRANSACTION)开始事务,然后是 LOCK TABLES,并且在提交事务之前不要调用 UNLOCK TABLES明确地。例如,如果您需要写入表 t1 并从表 t2 读取,您可以这样做:

当你调用 LOCK TABLES 时,InnoDB 内部会使用自己的表锁,而 MySQL 会使用自己的表锁。InnoDB 在下一次提交时释放它的内部表锁,但是要让 MySQL 释放它的表锁,你必须调用 UNLOCK TABLES。你不应该让 autocommit = 1,因为 InnoDB 在调用 LOCK TABLES 后立即释放它的内部表锁,死锁很容易发生。如果 autocommit = 1,InnoDB 根本不会获取内部表锁,以帮助旧应用程序避免不必要的死锁。

另一方面,从这个页面我们有 https://dev.mysql.com/doc/refman/5.6/en/commit.html

要为单个语句系列隐式禁用自动提交模式,请使用 START TRANSACTION 语句:

使用 START TRANSACTION,自动提交保持禁用状态,直到您使用 COMMIT 或 ROLLBACK 结束事务。然后自动提交模式恢复到之前的状态。

所以,如果 withSTART TRANSACTION禁用了自动提交,那么为什么在表锁定部分它说正确的方法是to begin a transaction with SET autocommit = 0 (not START TRANSACTION). 我错过了什么还是这两者之间存在矛盾?我可以START TRANSACTION与表锁定一起使用吗?我正在使用 InnoDB。

谢谢

0 投票
1 回答
28695 浏览

mysql - Mysql - 序列化失败:1213 尝试获取锁时发现死锁;尝试重启事务

我有menus,categoriesproducts表。我正在使用 mysql 5.5,所有表都是 innoDB,并且在所有情况下 id 都是具有自动增量的主键(int)。

多个脚本可以并行运行,执行包含以下逻辑的同一个 php 文件。

如果找到选择结果后,它的状态更新为1(否则我回滚并释放锁)

如果最后一个查询成功,我运行

否则

在此之后,脚本向该产品的 url 发出 curl 请求,以从中获取一些内容并相应地更新产品的行

因此,脚本在上述表上获取 X 锁,从 products 表中获取状态为 0(表示 - TODO)的一行,尝试将其状态设置为 1(表示 PENDING),然后解锁表。之后尝试在 php 中执行一些逻辑,最后尝试更新产品表 - 将内容列和状态更新为 2(表示完成)。

如果我并行运行 5 个脚本,在最后一步运行几分钟后(将产品更新为 DONE),我会收到此错误

当 2 个事务相互等待以相反的顺序更新相同的行时,我理解死锁的一般概念,但是在这种情况下我无法弄清楚死锁的原因。我的意思是脚本正在工作并以相同的顺序锁定表,因此如果一个脚本已锁定products(和其他)表,获取排他锁,另一个脚本应该在队列中等待这些锁被释放,所以它不应该导致死锁.
另一方面,每个脚本都在选择状态为 -> 0 的产品并尝试更新为 1,并且在从 1 到 2 的同一“会话”期间,所以我看不出这如何成为死锁的原因。我在这里想念什么?

编辑:

虽然我没有提到我如何使用类别和菜单表的信息,但我确实需要获取它们,它们的使用并不重要,因为我没有对它们进行任何数据库处理。

我曾经使用行级锁定SELECT FOR UPDATE,但是我遇到了像这个问题MySQL InnoDB dead lock on SELECT with exclusive lock (FOR UPDATE)这样的死锁,所以,我不得不将代码更改为表级锁定

谢谢

0 投票
0 回答
82 浏览

mysql - 如何在mysql中的元数据锁定期间检查表是否为空

我需要维护 ping 服务,该服务必须每 20 秒检查一次特定表是否为空。但是,有时脚本会在该表上执行导致元数据锁定的工作。该脚本有时可以运行数小时。这会导致 ping 请求陷入“等待元数据锁定”状态并很快堆积起来。有时这会导致“连接过多”错误。

我的问题是:有没有办法检查表是否为空,不关心是否有锁?如果不是,还有哪些其他可能的解决方案?

我正在使用带有 RDS mysql 的 Rails 3.2。

0 投票
2 回答
393 浏览

oracle - 由于 oracle 锁,应用程序变得无响应

该应用程序使用官网提供的 JDBC 驱动程序连接到 oracle 11G 数据库。当来自连接到同一架构的不同实例的许多用户(大约 50 个)开始使用该应用程序时,我在应用程序周围遇到了一些冻结,当我运行查询以获取锁定会话和锁定对象时,我发现只有“行独占”锁定类型,通常不应锁定所有表并允许多个会话执行 DML 查询。因此,我的问题是行独占表何时可以锁定整个表,否则会引发这些冻结。

注意:我在论坛上环顾四周,看到了一些 MAXTRANS 和 ITL 配置,这些参数会导致这些冻结吗?

谢谢

0 投票
0 回答
152 浏览

sql-server - SQL Server 中简单表锁的模式

我一直在阅读有关事务隔离级别和表提示的 MSDN,以了解在 SQL Server 中执行 2 步插入时我需要做什么才能以独占方式锁定表。我想出了两种方法来做到这一点,并想知道这些方法之间有什么区别。

这个答案显示了如何使用提示(https://stackoverflow.com/a/23759307/545430):

我想我也可以通过设置隔离级别来实现我的目标:

当我的事务插入这个新行时,我锁定整个表以防止任何更新是很重要的。这两种方法会产生相同的结果:表被 INSERT 和 UPDATE 命令锁定吗?

0 投票
0 回答
83 浏览

mysql - 并发 MYSQL 过程调用使用不相关的 SELECT 语句返回不同的结果

我在我的 MYSQL 应用程序中遇到了一些非常奇怪的事务行为。

我已经设法将问题减少到一个小的孤立测试用例,我在下面包含的代码:

重现步骤:

  1. 在上面的脚本中运行以创建一个测试数据库、两个表和一个存储过程。
  2. 在两个单独的连接中,尽可能接近同时运行存储过程(SLEEP如果需要更长的时间,可以增加时间):

    /li>

问题

当通过两个单独的连接同时执行时,该SELECT COUNT(*) FROM `tbl_test`;语句为两个调用返回不同的值。

当我按照上述步骤操作时,我会1从两个过程调用中的第一个和0第二个返回。

我对事务行为和表锁定的理解是,当第一次调用到达INSERT语句时,它将创建一个锁。第二个过程调用将到达同一行,但必须等到第一个调用的事务已提交。增加睡眠时间强化了这个想法,因为第二次通话需要两倍的时间才能完成。但是,如果是这种情况,那么第二个过程调用应该从第一个调用中提取插入,并且两个结果都应该等于1.

TL; DR 我希望两者都相等1

请注意,我使用READ_COMMITTED的是我的事务隔离级别。

我已经使用MYSQL server和测试了这个MariaDB

进一步的怪异

所以在这一点上,我认为我的理解是不正确的。但是,我随后注意到,通过删除该行SELECT * FROM `tbl_test2`;,结果突然产生了预期值!

我一直在尝试使用该脚本,但本质上,包括在该行导致意外结果SELECT之前对数据库中任何表的语句。INSERT我完全不知道为什么会这样。

问题

  1. 我对预期交易行为的理解是否正确?
  2. 为什么对不SELECT相关表的语句会导致事务锁定失败?

如果有人能对此有所了解,我将不胜感激!

0 投票
0 回答
78 浏览

c# - 异步锁定 SQL Server 表的例程

我想编写一个例程,它应该能够在指定的时间内锁定表并在任何等待之前异步返回。

我写了以下代码

但我没有得到想要的结果。myCommand.ExecuteNonQueryAsync();is not lock the table while myCommand.ExecuteNonQuery();locks the table but waiting for the specified time before return. 我希望它异步发生。任何帮助深表感谢。

0 投票
3 回答
11214 浏览

teradata - Teradata - 如何在不锁定作者的情况下进行选择?(锁定行访问与锁定表访问)

我正在开发一个从 Teradata DWH 获取一些数据的应用程序。DWH 开发人员告诉我LOCK ROW FOR ACCESS在所有SELECT查询之前使用以避免延迟对该表的写入。

非常熟悉 MS SQL Servers 的WITH(NOLOCK)提示,我认为LOCK ROW FOR ACCESS它是等价的。但是,INSERTUPDATE语句不允许使用LOCK ROW FOR ACCESS(我不清楚为什么会失败,因为它应该应用于语句选择的表,而不是我插入的表):

我已经看到LOCKING TABLE ... FOR ACCESS可以使用它,但不清楚它是否符合我的需要(NOLOCK等效 - 不要阻止写入)。

问题:在 语句中选择时,我应该使用什么提示来最大程度地减少写入延迟?INSERT

0 投票
2 回答
1507 浏览

php - 防止酒店预订系统 PHP/MySQL 中的竞争条件和锁定表

我正在建立一个酒店式的预订系统,但我迷路了。我在添加预订的确切预订时刻卡住了,我担心即将到来的情况。

我的流程非常简单,它允许多个用户完成同一个房间的预订过程,直到其中一个用户先于其他用户按下预订按钮。预订信息保留在会话中,并且在有人到达最后一步并按“预订”之前永远不会存储在数据库中。在每一步中,系统都会检查房间是否可用,如果不可用,则会给出错误页面。

现在的问题是防止竞争条件与最后一个强制检查是否仍有足够的房间相结合:

当用户在最后一步时,他/她选择付款方式并按下预订按钮。在检查所选付款选项是否正常(表单数据未更改)后,它会重定向到预订控制器,其中:

预订控制器

预订型号:

上面提到的表是 InnoDB,#__bookings 保存预订,#__booking_room 保存所选房间的信息(如 avg_price、房间数等),它有一个外键到 #__rooms 和一个到 #__bookings

我在担心什么?

1 - 我在最后一次可用性检查期间使用了其他表,而不是两个锁定的表,并且给了我错误。

2 - 当第二个用户的执行到达表锁定点时,它是等到他们获得空闲还是引发错误/异常?我可以捕获异常并将用户重定向到错误页面,但小盒表并不意味着已放置预订,在保存信息时可能会出现任何问题。

我希望我的工作流程没问题,请让我知道我是否可以继续,或者我应该改进我的代码。

谢谢

编辑:

值得一提的是,商业理念就像 Expedia、预订等,您可以在每次预订时选择更多的房间类型和单位。事实上,我的房间桌子不是针对特定/真实房间的,而是针对房间类型,如果尚未预订,则每天都有固定数量的可用单元。

0 投票
3 回答
21656 浏览

php - 请问laravel数据库事务锁表吗?

我使用 laravel5.5 的数据库事务进行在线支付应用。我有一个 company_account 表来记录每笔付款(type、、、、amount)。创建新记录时,我需要访问最后一条记录。所以我需要在事务的时候用读写表锁来锁表,以避免同时进行多次支付。create_atgross_incomegross_income

我参考了 laravel 的文档,但我不确定事务是否会锁定表。如果事务将锁定表,锁定类型是什么(读锁、写锁或两者兼有)?


代码:

参考:
如何将参数传递给 Laravel DB::transaction()