有人可以告诉我是否可以从一个过程中调用另一个过程,并且如果任一过程的任何部分失败,则回滚所有内容?
如果这是可能的,有人可以向我展示一个如何实施的小例子吗?
EDIT:过程“b”失败,但过程“a”仍然向表“a”中插入一行。据我了解,如果插入的任何部分失败,则所有内容(两个插入)都会回滚,而这里不会发生这种情况。问题是为什么不呢?
程序“a”
BEGIN
DECLARE b INT DEFAULT 0;
DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK;
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
INSERT INTO a(a)
VALUES(iA);
CALL b(iB,LAST_INSERT_ID(),@b);
SELECT @b INTO b;
IF b !=1 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END
程序“b”
BEGIN
DECLARE b INT DEFAULT 0;
DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK;
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
INSERT INTO b VALUES(iB,id);
SET b=1;
COMMIT;
END;
您将需要在两个过程中处理事务,但是调用另一个过程的过程应该检查返回值并据此回滚其事务。这是内部过程的示例:
如何检测MySQL存储过程的回滚? https://stackoverflow.com/questions/4076566/how-to-detect-a-rollback-in-mysql-stored-procedure
然后你会检查p_return_code
并回滚父事务。
EDIT:
我认为正在发生的事情是内部 SP COMMIT 或 ROLLBACK 影响外部 SP TRANSACTION。这段代码对我有用,如果内部 SP 失败,它会回滚两个插入语句。第一次调用 ab() 有效,新的用户记录被插入,新的游戏记录被插入,如果我们从游戏表中删除记录并再次运行 ab() ,因为用户 ID 已经存在,它会回滚游戏表插入:
create procedure ab()
BEGIN
START TRANSACTION;
INSERT INTO games (title) VALUES ('bad game');
CALL ba(@ret);
IF @ret!=0 THEN
ROLLBACK;
ELSE
COMMIT;
END IF;
END;
create procedure ba(OUT return_value tinyint unsigned)
BEGIN
DECLARE exit handler for sqlexception
BEGIN
set return_value = 1;
END;
INSERT INTO users (id) VALUES(1);
set return_value = 0;
END;
测试使用call ab();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)