在MySQL文档中有一个我不明白的声明:
使用LOCK TABLES和UNLOCK TABLES与事务表(如InnoDB表)的正确方法是以SET autocommit = 0(不是START TRANSACTION)开始一个事务,然后是LOCK TABLES,在明确提交事务之前不要调用UNLOCK TABLES。 (https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html)
即使在文档中进行了大量搜索并研究了" autocommit"和#34; START TRANSACTION",我真的不明白为什么要使用 autocommit 而不是 START TRANSACTION 。有任何想法吗?感谢
答案 0 :(得分:6)
LOCK TABLES
隐式提交交易
因此,如果您按照以下顺序执行操作,则不会执行您的操作:
BEGIN;
/* I think I'm in transaction 1 */
LOCK TABLES ...;
/* but that implicitly committed transaction 1 */
UPDATE blab blah ...;
/* I think I'm still in transaction 1, but this update caused
a new transaction 2 to begin and autocommit */
UPDATE yadda yadda ...;
/* I think I'm still in transaction 1, but this update caused
a new transaction 3 to begin and autocommit */
COMMIT;
使用事务的关键是当您需要运行多个更新时,但您希望所有更新的结果一起提交或根本不提交。
上面的示例没有原子地提交两个更新。他们每个人都有自己的自动交易。因此,一个人可能会成功,但另一个人不会。
建议采取以下措施:
SET autocommit=0;
LOCK TABLES ...;
/* that implicitly committed any outstanding transaction, but that's OK */
UPDATE blab blah ...;
/* because autocommit=0, a new DML statement implicitly starts a new transaction */
UPDATE yadda yadda ...;
/* the new transaction is still open */
COMMIT;
UNLOCK TABLES;
这会以原子方式同时提交两个更新。
为什么不只是LOCK TABLES然后BEGIN开始交易?
https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html说:
开始事务(例如,使用START TRANSACTION)隐式提交任何当前事务并释放现有表锁。
这对我来说很奇怪。显式BEGIN(或START TRANSACTION)释放表锁,但事务的隐式启动不会?在我看来,这个功能充满了WTF。但这就是所记录的内容。
答案 1 :(得分:0)
从不(好吧,我没有听说过案例)在InnoDB中使用 LOCK TABLES
。 LOCK TABLES
是一把大锤。它可能会严重降低您的系统速度。
对于某些应用, autocommit=ON
没问题。
对于某些应用,请使用 BEGIN
(START TRANSACTION
)和COMMIT
- 让它们保持干净配对。
不使用 autocommit=OFF
,很容易忘记COMMIT
。
请谨慎记住 DDL 语句COMMIT
。 (直到MySQL 8.0。)