DELIMITER $$
CREATE PROCEDURE my_proc()
BEGIN
START TRANSACTION;
UPDATE test SET num = 5;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred';
ROLLBACK;
COMMIT;
END$$
DELIMITER ;
型 然后,调用my_proc()会得到错误,但num不会回滚到2,如下所示:
mysql> CALL my_proc();
ERROR 1644 (45000): An error occurred
...
mysql> SELECT num FROM test;
+------+
| num |
+------+
| 5 |
+------+
DELIMITER $$
CREATE PROCEDURE my_proc()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
UPDATE test SET num = 5;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred';
COMMIT;
END$$
DELIMITER ;
型 或者,您可以在my_proc()过程中回滚事务,如下所示:
DELIMITER $$
CREATE PROCEDURE my_proc()
BEGIN
DECLARE `_rollback` BOOL DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
SET `_rollback` = 1;
END;
START TRANSACTION;
UPDATE test SET num = 5;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'An error occurred';
IF `_rollback` THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END$$
DELIMITER ;
5条答案
按热度按时间vvppvyoh1#
查看http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
基本上,您声明错误处理程序,它将调用回滚
字符串
wswtfjt72#
只是一个替代的代码由rkosegi,
字符串
gcuhipw93#
[* 这只是一个解释,其他答案中没有提到 *]
至少在最近的MySQL版本中,你的第一个查询不是提交的。
如果你在同一个会话下查询它,你会看到更改,但是如果你从不同的会话查询它,更改不在那里,它们不是提交的。
怎么回事?
当你打开一个事务,并且其中的一个查询失败时,事务保持打开状态,它不会提交也不会回滚更改。
因此,小心,任何使用以前的查询(如
SELECT ... FOR SHARE/UPDATE
、UPDATE
、INSERT
或任何其他锁定查询)锁定的表/行将保持锁定,直到该会话被杀死(并执行回滚),或者直到下面的查询显式提交它(COMMIT
)或implicitly,从而使部分更改永久(这可能在几个小时后发生,而事务处于等待状态)。这就是为什么解决方案涉及在发生错误时立即向
ROLLBACK
声明处理程序。额外
在处理程序内部,您还可以使用
RESIGNAL
重新引发错误,否则存储过程将执行 “Successfully”:字符串
zynd9foi4#
下面是一个在出错时回滚并返回错误代码的事务示例。
字符串
这是假设自动提交设置为0。希望这有帮助。
vs3odd8k5#
您可以在procedure中使用transaction。* 我们不能在function中使用transaction。
例如,创建
test
表,如下所示:字符串
然后,插入num为
2
的行,如下所示:型
然后,创建
my_proc()
过程,将num
更新为5
,然后通过SIGNAL statement导致错误,然后在事务(START TRANSACTION and COMMIT statements)中使用ROLLBACK statement回滚,如下所示:型
然后,调用
my_proc()
会得到错误,但num
不会回滚到2
,如下所示:型
现在,您可以使用DECLARE ... HANDLER statement回滚
my_proc()
过程中的事务,如下所示。* 请注意,没有事务的my_proc()
过程(START TRANSACTION
和COMMIT
语句)不会将num
回滚到2
:型
或者,您可以在
my_proc()
过程中回滚事务,如下所示:型
然后,调用
my_proc()
不会得到错误,因为错误由DECLARE ... HANDLER
语句处理,然后num
回滚到2
,如下所示:型