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

ral*_*okt 67 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;after COMMIT;或者ROLLBACK;

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

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

OMG*_*ies 67

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

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

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

SET autocommit = 0
Run Code Online (Sandbox Code Playgroud)

显式事务是当语句被包装在显式定义的事务代码块中时 - 对于MySQL,即START TRANSACTION.它还需要在事务结束时明确地制作COMMITROLLBACK声明.嵌套事务超出了本主题的范围.

隐式事务与显式事务略有不同.隐式事务不需要明确定义事务.但是,与显式事务一样,它们需要提供COMMITROLLBACK声明.

结论

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

这意味着你应该使用:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;
Run Code Online (Sandbox Code Playgroud)

......并且仅COMMIT;在结果正确时使用.

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

附录

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

  • 哇,那很快:-)非常感谢!我不太明白为什么我需要SET autocommit = 0; 在上面的例子中; 没有开始交易意味着什么?如果没有,有什么区别? (8认同)
  • 我想`SET autocommit = 0;`只是一个偏好,不要忘记使用trasactions (3认同)

mik*_*ikl 19

InnoDB中,START TRANSACTION;在这个引擎中是官方推荐的交易方式,而不是SET AUTOCOMMIT = 0;(除非用于优化只读SET AUTOCOMMIT = 0;交易,否则不要用于InnoDB中的交易).承诺.COMMIT;

您可能希望SET AUTOCOMMIT = 0;InnoDB中用于测试目的,而不是精确地用于事务.

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

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

一般使用交易的例子:

/* InnoDB */
START TRANSACTION;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

COMMIT; /* SET AUTOCOMMIT = 1 might not set AUTOCOMMIT to its previous state */

/* MyISAM */
SET AUTOCOMMIT = 0;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

SET AUTOCOMMIT = 1; /* COMMIT statement instead would not restore AUTOCOMMIT to 1 */
Run Code Online (Sandbox Code Playgroud)