Can someone tell me if it is possible to call another procedure from within a procedure and if any part of either procedure fails, roll everything back?
If this is possible, can someone please show me a tiny example of how this would be implemented?
EDIT: Procedure “b” fails but procedure “a” still inserts a row into table “a”. It’s my understanding that if any part of the insert fails that everything (both inserts) is rolled back which is not happening here. The questions is why not?
Procedure “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
Procedure “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;
You will need to handle transactions in both procedures, but the proc that is calling the other, should check for the return value and rollback it’s transactions based on that. Here is an example of the inner proc:
How to detect a rollback in MySQL stored procedure?
you would then check for
p_return_codeand do a rollback of the parent transaction.What I think is happening is that inner SP COMMIT or ROLLBACK affect outer SP TRANSACTION. This code works for me, if inner SP fail it rolls back both insert statements. First call to ab() works, new user record gets inserted and new game record gets inserted, if we remove record from the games table and run ab() again, because user id already exists it rolls back games table insert:
To test use
call ab();