MySQL:使用自动提交锁定表与启动事务

标签 mysql transactions innodb autocommit

在 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/

相关文章:

java - Spring事务内部

innodb - mysqldump 备份缺少所有 innodb 表,但没有 MyISAM 表

mysql - 重组/分区数据库表

linux - 为什么 sqlite 独占事务不尊重 linux 上的独占?

mysql - 具有可重复读取隔离级别的 MySQL 中的更新插入

mysql - 当所有表都是 MYISAM 时,打开 INNODB 引擎是否安全?

innodb - Cpanel sql 备份失败

sql - MySQL LIMIT 是在 ORDER BY 之前还是之后应用的?

php - 此集合实例上不存在属性 [stats]

java - 执行 JDBC 事务时出现重复键异常