我需要在单个原子事务中执行多个插入。例如:
start transaction;
insert ...
insert ...
commit;
然而,当 MySQL 遇到错误时,它只会中止导致错误的特定语句。例如,如果第二个插入语句中有错误,提交仍将发生并且第一个插入语句将被记录。因此,当错误发生时,MySQL 事务并不是真正的事务。为了克服这个问题,我使用了一个错误退出处理程序来回滚事务。现在交易默默地中止了,但我不知道是什么问题。
所以这是你的难题:
如何让 MySQL 在遇到错误时中止事务,并将错误代码传递给调用者?
最佳答案
How can I both make
MySQL
abort a transaction when it encounters an error, and pass the error code on to the caller?
MySQL
确实将错误代码传递给调用者,并且基于此错误代码,调用者可以自由决定是否要提交目前已完成的工作(忽略此特定 INSERT
语句的错误)或回滚事务。
这不同于 PostgreSQL
它总是在出错时中止事务,这种行为是许多问题的根源。
更新:
使用无条件 ROLLBACK
是一种不好的做法在存储过程中。
存储过程是可堆叠的,而事务不是,所以 ROLLBACK
在嵌套存储过程中将回滚到事务的最开始,而不是存储过程执行的状态。
如果您想使用事务来恢复错误时的数据库状态,请使用 SAVEPOINT
构造和 DECLARE HANDLER
回滚到保存点:
CREATE PROCEDURE prc_work()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK TO sp_prc_work;
SAVEPOINT sp_prc_work;
INSERT …;
INSERT …;
…
END;
任一插入失败都将回滚过程所做的所有更改并退出。
关于MySQL事务难题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547592/