我正在阅读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 - 看到隔离级别意味着存在交易,这意味着自动提交应该是关闭的吗?
如果在开始交易和设置自动提交之间存在另一个差异(除了上述的差异之外),它是什么?
答案 0 :(得分:64)
了解数据库的事务(自动提交,显式和隐式)处理可以使您不必从备份中恢复数据。
事务控制数据操作语句以确保它们是原子的。 “原子”意味着交易要么发生,要么不发生。向数据库发出事务完成信号的唯一方法是使用COMMIT
或ROLLBACK
语句(根据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
。它还需要在事务结束时显式创建COMMIT
或ROLLBACK
语句。嵌套事务超出了本主题的范围。
隐式交易与显式交易略有不同。隐式事务不需要明确定义事务。但是,与显式事务一样,它们需要提供COMMIT
或ROLLBACK
语句。
显式交易是最理想的解决方案 - 它们需要一个声明COMMIT
或ROLLBACK
来完成交易,如果有需要,其他人可以清楚地说明正在发生的事情。如果以交互方式使用数据库,则隐式事务是正常的,但只有在测试结果后才能指定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;