在 MySQL 文档中有一个声明我不明白:
The correct way to use LOCK TABLES and UNLOCK TABLES with transactional tables, such as InnoDB tables, is to begin a transaction with SET autocommit = 0 (not START TRANSACTION) followed by LOCK TABLES, and to not call UNLOCK TABLES until you commit the transaction explicitly. (https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html)
即使在文档中搜索了很多并研究了“autocommit”和“START TRANSACTION”的描述之后,我真的不明白为什么要使用 autocommit 而不是 START TRANSACTION强>。有任何想法吗?谢谢
最佳答案
根据 https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html,
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;
这将以原子方式同时提交两个更新。
为什么不锁定表然后开始交易呢?
https://dev.mysql.com/doc/refman/5.7/en/lock-tables-and-transactions.html说:
Beginning a transaction (for example, with START TRANSACTION) implicitly commits any current transaction and releases existing table locks.
我觉得很奇怪。显式 BEGIN(或 START TRANSACTION)会释放表锁,但事务的隐式启动不会?在我看来,该功能充满了 WTF。但这就是记录的内容。
关于MySQL:使用自动提交锁定表与启动事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50539828/