【问题标题】:MySQL - rolling back transactions in case of embedded proceduresMySQL - 在嵌入式过程的情况下回滚事务
【发布时间】:2016-03-10 16:59:37
【问题描述】:

如果发生错误(使用 SIGNAL),我会尝试在过程中回滚事务。 我有两个问题:

  1. 如果发生错误,我想停止执行语句 1
  2. 如果过程 1 中出现错误,我想停止执行 Stateemtn 2。

程序 1:

CREATE DEFINER=`edgar`@`%` PROCEDURE some_sp (IN param INT)
BEGIN

    DECLARE `_rollback` BOOL DEFAULT 0;

    DECLARE new_legal_entity_id INT;

    DECLARE specialty CONDITION FOR SQLSTATE '45000';
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET _rollback = 1;

    START TRANSACTION;

    CASE -- Some condition 
        BEGIN
            SIGNAL specialty
            SET MESSAGE_TEXT = 'Error message';
        END;
    ELSE BEGIN END;
    END CASE;

    INSERT INTO .... -- Statement 1

    COMMIT;
    END

程序 2:

CREATE DEFINER=`edgar`@`%` PROCEDURE some_sp_1 (IN param INT)
BEGIN

    DECLARE `_rollback` BOOL DEFAULT 0;

    DECLARE new_legal_entity_id INT;

    DECLARE specialty CONDITION FOR SQLSTATE '45000';
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET _rollback = 1;

    START TRANSACTION;

    CALL some_sp(some_param);
    INSERT INTO .... -- Statement 2

    COMMIT;
    END

我已阅读 thisthis ,但仍无法使代码正常工作

【问题讨论】:

    标签: mysql error-handling transactions rollback


    【解决方案1】:

    试试:

    DELIMITER $$
    
    DROP TABLE IF EXISTS `t`$$
    DROP PROCEDURE IF EXISTS `some_sp_1`$$
    DROP PROCEDURE IF EXISTS `some_sp`$$
    
    CREATE TABLE `t`(
      `id` INT UNSIGNED
    )$$
    
    CREATE PROCEDURE `some_sp`(IN `param` INT)
    BEGIN
      DECLARE `specialty` CONDITION FOR SQLSTATE '45000';
      IF `param` THEN
        SIGNAL `specialty`;
      END IF;
      INSERT INTO `t` SELECT 1;
    END$$
    
    CREATE PROCEDURE `some_sp_1`(IN `param` INT)
    BEGIN
      DECLARE `_rollback` BOOL DEFAULT FALSE;
      DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` := TRUE;
      START TRANSACTION;
      CALL `some_sp`(`param`);
      IF `_rollback` THEN
        ROLLBACK;
      ELSE
        -- INSERT INTO `t1` SELECT 2; -- fail, t1 not exist
        INSERT INTO `t` SELECT 2;
        IF `_rollback` THEN
          ROLLBACK;
        ELSE
          COMMIT;
        END IF;
      END IF;
    END$$
    
    DELIMITER ;
    
    CALL `some_sp_1`(0);
    -- CALL `some_sp_1`(1);
    
    SELECT `id` FROM `t`;
    

    【讨论】:

    • 不,@wchiquito,这似乎对我不起作用。看我的回答
    • @EdgarNavasardyan: SQL Fiddle 正在运行测试。
    猜你喜欢
    • 2012-09-13
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    相关资源
    最近更新 更多