当前位置: 首页 > 知识库问答 >
问题:

带有表锁定的Mysql事务

章高爽
2023-03-14

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

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

对事务表(如InnoDB表)使用LOCK TABLES和UNLOCK TALES的正确方法是以SET autocommit=0(而不是START transaction)开始事务,后跟LOCK TABES,并且在显式提交事务之前不要调用UNLOCK TABLES。例如,如果您需要写入表t1并从表t2读取,可以这样做:

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;

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

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

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

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

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

因此,如果使用<code>START TRANSACTION</code>禁用了自动提交,那么为什么在表锁定部分中会说正确的方法是<code>以SET autocommit=0(而不是START TRASSACTION)</code>开始事务。我是错过了什么,还是这两者之间有矛盾?我可以使用<code>START TRANSACTION</code>和表锁定吗?我正在使用InnoDB。

谢谢

共有1个答案

相旭
2023-03-14

https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html

  • LOCK TABLES不是事务安全的,并且在尝试锁定表之前隐式提交任何活动事务。
  • 开始事务(例如,使用START TRANSACT ION)隐式提交任何当前事务并释放现有表锁。
 类似资料:
  • 问题内容: 我对事务与锁定表有些困惑,以确保数据库完整性,并确保SELECT和UPDATE保持同步,并且没有其他连接干扰它。我需要: 我需要确保没有其他查询会干扰并执行相同的操作(在该连接完成更新行之前读取“旧值”。 我知道我可以默认为只确保一次只有1个连接正在执行此操作,并在完成后将其解锁,但这似乎有点过头了。将它包装在事务中是否会做同样的事情(确保没有其他连接会尝试同一进程而另一个仍在处理)?

  • 问题内容: 最近几天,随机地,我的网站变得非常缓慢。我开始尽力调查。我看到MySQL进程正在使用服务器可用内存的85%-95%(我也应该升级我的内存吗?)。 我检查了我的MySQL进程日志,发现有很多查询,其中包括: 等待表级锁定 但是我还注意到,所有这些带有“表级锁定”的查询都是与表有关的查询。 我还有20个其他表,它们具有不变的查询,但是我在列表中没有看到它们。.所以我猜问题出在users表上

  • 13.4.1. START TRANSACTION, COMMIT和ROLLBACK语法 13.4.2. 不能回滚的语句 13.4.3. 会造成隐式提交的语句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT语法 13.4.5. LOCK TABLES和UNLOCK TABLES语法 13.4.6. SET TRANSACTION语法 13.4.7. XA事务 MyS

  • 问题内容: 如果我有如下代码: 在开始和提交之间,正在读取的表是否被锁定,并且随后是否会在多用户环境中引起问题,在该环境中,当另一个用户调用上面的相同代码时会发生问题? 如果以上情况有问题,我们是否应始终尝试缩短交易时间?并为此提供便利,而不是在懒惰的关系上调用getter方法,这是否意味着最好使交易简短并为父母的子女手动查找? 问题答案: Hibernate不会做任何事情来显式锁定您从中读取的表

  • 我是数据库锁定新手,所以请耐心等待。 我在一个文件中有我的 SELECT 语句,在另一个文件中有我的 UPDATE 语句。两者都在文件的开头建立连接,然后在文件末尾断开连接。我正在尝试做的是锁定 select 语句中的表行,如果用户取消或更新,则释放该锁定。 我试过咨询锁,但当我断开连接时,它们会解锁。我尝试过的所有其他锁都做同样的事情。 有没有一种方法,我可以实现我想要在我的当前数据库结构,或者

  • 7.3.1. 锁定方法 7.3.2. 表锁定事宜 7.3.1. 锁定方法 MySQL 5.1支持对MyISAM和MEMORY表进行表级锁定,对BDB表进行页级锁定,对InnoDB表进行行级锁定。 在许多情况下,可以根据培训猜测应用程序使用哪类锁定类型最好,但一般很难说出某个给出的锁类型就比另一个好。一切取决于应用程序,应用程序的不同部分可能需要不同的锁类型。 为了确定是否想要使用行级锁定的存储引擎