SET autocommit = 1和mysql中的START TRANSACTION之间的区别(我错过了什么?)

时间:2010-06-01 14:38:49

标签: mysql sql transactions

我正在阅读MySQL中的交易,我不确定我是否已经正确掌握了一些具体内容,我想确保我理解正确,所以这里有。我知道一个事务应该做什么,我只是不确定我是否理解语句语义。

所以,我的问题是,有什么不对,(如果是这样的话,有什么不对的话),有以下几点:

默认情况下,MySQL中启用了自动提交模式。

现在,SET autocommit=0;将开始一个事务,SET autocommit=1;将隐式提交。可以COMMIT;以及ROLLBACK;,在这两种情况下,自动提交仍然设置为0(并隐式启动新事务)。

START TRANSACTION;SET autocommit=0;发生之前,

COMMIT;基本上会ROLLBACK;

换句话说,START TRANSACTION;SET autocommit=0;是等效的,除了START TRANSACTION;相当于在SET autocommit=0;之后隐式添加COMMIT;ROLLBACK;

如果是这种情况,我不明白http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_serializable - 看到隔离级别意味着存在交易,这意味着自动提交应该是关闭的吗?

如果在开始交易和设置自动提交之间存在另一个差异(除了上述的差异之外),它是什么?

4 个答案:

答案 0 :(得分:64)

了解数据库的事务(自动提交,显式和隐式)处理可以使您不必从备份中恢复数据。

事务控制数据操作语句以确保它们是原子的。 “原子”意味着交易要么发生,要么不发生。向数据库发出事务完成信号的唯一方法是使用COMMITROLLBACK语句(根据ANSI-92,遗憾的是不包括创建/开始事务的语法,因此它是特定供应商)。 COMMIT应用在事务中进行的更改(如果有)。 ROLLBACK忽略了事务中发生的任何操作 - 当UPDATE / DELETE语句出现意外情况时非常需要

通常,单个DML(插入,更新,删除)语句在自动提交事务中执行 - 它们在语句成功完成后立即提交。这意味着在像您这样的情况下运行语句之前,没有机会将数据库回滚到状态。当出现问题时,唯一可用的恢复选项是从备份重建数据(提供一个存在)。在MySQL中,autocommit is on by default for InnoDB - MyISAM不支持事务。可以使用以下方法禁用它:

SET autocommit = 0

显式事务是指语句被包装在显式定义的事务代码块中 - for MySQL, that's START TRANSACTION。它还需要在事务结束时显式创建COMMITROLLBACK语句。嵌套事务超出了本主题的范围。

隐式交易与显式交易略有不同。隐式事务不需要明确定义事务。但是,与显式事务一样,它们需要提供COMMITROLLBACK语句。

结论

显式交易是最理想的解决方案 - 它们需要一个声明COMMITROLLBACK来完成交易,如果有需要,其他人可以清楚地说明正在发生的事情。如果以交互方式使用数据库,则隐式事务是正常的,但只有在测试结果后才能指定COMMIT语句。彻底坚决有效。

这意味着你应该使用:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

...只有在结果正确时才使用COMMIT;

也就是说,UPDATE和DELETE语句通常只返回受影响的行数,而不是特定的详细信息。将这些语句转换为SELECT语句&检查结果以确保 之前 正确尝试UPDATE / DELETE语句。

附录

DDL(数据定义语言)语句是自动提交的 - 它们不需要COMMIT语句。 IE:表,索引,存储过程,数据库和视图创建或更改语句。

答案 1 :(得分:17)

InnoDB 中,您有START TRANSACTION;,在此引擎中是官方推荐的交易方式,而不是SET AUTOCOMMIT = 0;(不要使用{{1}对于 InnoDB 中的事务,除非它用于优化只读事务。提交SET AUTOCOMMIT = 0;

您可能希望在 InnoDB 中使用COMMIT;进行测试,而不是精确地用于交易。

MyISAM 中,您没有SET AUTOCOMMIT = 0;。在此引擎中,使用START TRANSACTION;进行交易。使用SET AUTOCOMMIT = 0;COMMIT;进行提交(下面的MyISAM示例评论中解释了差异)。您也可以在InnoDB中以这种方式进行交易。

来源:http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit

一般使用交易的例子:

SET AUTOCOMMIT = 1;

答案 2 :(得分:2)

如果你想使用回滚,那么使用启动事务,否则会忘记所有这些事情,因为MySQL默认将autocommit设置为1。

答案 3 :(得分:0)

https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html

对事务表(例如InnoDB表)使用LOCK TABLES和UNLOCK TABLES的正确方法是,先以SET autocommit = 0(不是START TRANSACTION)后跟LOCK TABLES开始事务,并且直到您调用UNLOCK TABLES为止显式提交事务。例如,如果您需要写入表t1并从表t2中读取,则可以执行以下操作:

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