如果未达到COMMIT TRANSACTION,则自动回滚

时间:2011-05-25 09:00:02

标签: mysql transactions rollback

请考虑以下事项:

START TRANSACTION;

BEGIN;

INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

/** Assume there is syntax error SQL here...**/
Blah blah blah

DELETE FROM prp_property1 WHERE environment_name = 'production';

COMMIT TRANSACTION;

问题:

我注意到事务会自动回滚并且记录插入尝试失败。

如果我没有像上面那样提供错误处理程序或错误检查以及ROLLBACK TRANSACTION,那么它是否安全,因为它似乎在上面的示例中执行工作,因为COMMIT TRANSACTION永远不会得到执行?

我假设事务立即回滚并在发生错误时立即丢弃。

5 个答案:

答案 0 :(得分:22)

不,一旦发生错误,事务就不会回滚。但您可能正在使用应用此策略的客户端应用程序。

例如,如果您使用的是mysql命令行客户端,那么它通常会在发生错误时停止执行并退出。在事务正在进行时退出确实会导致它被回滚。

当您编写自己的应用程序时,可以在回滚时控制策略,但也有一些例外:

  • 退出(即断开与数据库的连接)始终回滚正在进行的事务
  • 死锁或锁定等待超时隐式导致回滚

除了这些条件之外,如果您调用生成错误的命令,则会正常返回错误,您可以随意执行任何操作,包括提交事务。

答案 1 :(得分:8)

您可以使用程序更有效地执行此操作 Transaction with Stored Procedure in MySQL Server

答案 2 :(得分:6)

使用Mysql存储过程

   BEGIN

   DECLARE exit handler for sqlexception
      BEGIN
      ROLLBACK;
   END;

   DECLARE exit handler for sqlwarning
     BEGIN
     ROLLBACK;
   END;

   START TRANSACTION;

   INSERT INTO prp_property1 (module_name,environment_name,NAME,VALUE) VALUES ('','production','','300000');

   [ERROR]

   COMMIT;

   END

您可以设置警告或错误回滚,然后您不需要删除,事务中所有条目都将被删除。

答案 3 :(得分:4)

我想补充@MarkR已经说过的内容。错误处理,假设InnoDB引擎,如Mysql Server Documentation

中所述
  
      
  • 如果表空间中的文件空间不足,则会发生MySQL表错误,InnoDB会回滚SQL语句。
  •   
  • 事务死锁导致InnoDB回滚整个事务。
  •   
  • 重复键错误回滚SQL语句
  •   
  • 行太长错误会回滚SQL语句。
  •   
  • 其他错误主要由MySQL代码层检测(在InnoDB存储引擎级别之上),并且它们回滚相应的SQL语句
  •   

我的理解是当Mysql会话结束时(当php脚本结束时),任何未提交的内容都会被回滚。我还必须找到一个非常可靠的来源来支持这个陈述,所以不要相信我的话。

答案 4 :(得分:0)

我已经测试了这三种情况; mySQL不会自动回滚。

事务死锁导致InnoDB回滚整个事务。 重复键错误会回滚SQL语句 一行太长的错误将回滚SQL语句。

除非受影响的记录失败,否则其他记录将成功,除非您的应用程序明确调用“回滚”。