请考虑以下事项:
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
永远不会得到执行?
我假设事务立即回滚并在发生错误时立即丢弃。
答案 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语句。
除非受影响的记录失败,否则其他记录将成功,除非您的应用程序明确调用“回滚”。