簡體   English   中英

Mysql嵌套事務與回滾

[英]Mysql nested transaction with rollback

有人能告訴我是否有可能從一個程序中調用另一個程序,如果任何一個程序的任何部分失敗,請回滾所有內容?

如果可以,有人可以告訴我一個如何實現這個的小例子嗎?

編輯:過程“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;

您將需要在兩個過程中處理事務,但是調用另一個過程的proc應該檢查返回值並基於此回滾它的事務。 這是內部過程的一個例子:

如何檢測MySQL存儲過程中的回滾?

然后,您將檢查p_return_code並執行父事務的回滾。

編輯:

我認為發生的是內部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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM