在MySql存储过程中使用事务

现有如下的存储过程,执行插入操作。其中bill表中id为primary key,其它为字段为普通字段,没加任何索引与约束,多余的省略,不予展示。

DROP PROCEDURE IF EXISTS transactionTest;
CREATE PROCEDURE transactionTest()
BEGIN
    INSERT INTO bill(`id`, `money`,...) VALUES ('XYZPPb0e114211e7b45a000c29d19928', '6000.000000',...);
    INSERT INTO bill(`id`, `money`,...) VALUES ('XYZPPb0e114211e7b45a000c29d19928', '6000.000000',...);
END;

 

MySQL执行后产生异常,产生主键冲突,而且第一条插入的记录可以查找到,执行的操作并未回滚。

[SQL]CALL transactionTest();
[Err] 1062 - Duplicate entry 'XYZPPb0e114211e7b45a000c29d19928' for key 'PRIMARY'
 

为了在存储过程产生异常时进行回滚,需要使用事务。改写后的例子如下[1]。

DROP PROCEDURE IF EXISTS transactionTestWithRb;
CREATE PROCEDURE transactionTestWithRb()
BEGIN
    DECLARE exit HANDLER FOR SQLEXCEPTION
        BEGIN
            -- ERROR
            ROLLBACK;
        END;
        DECLARE EXIT HANDLER FOR SQLWARNING
        BEGIN
            -- WARNINGS
            ROLLBACK;
        END;
    START TRANSACTION;
    INSERT INTO bill(`id`, `money`,...) VALUES ('XYZPPb0e114211e7b45a000c29d19928', '6000.000000',...);
    INSERT INTO bill(`id`, `money`,...) VALUES ('XYZPPb0e114211e7b45a000c29d19928', '6000.000000',...);
    COMMIT;
END;

CALL transactionTestWithRb();
CREATE PROCEDURE addtest(IN name VARCHAR(255),IN job VARCHAR(255),IN add_time CHAR(10),OUT back int)
BEGIN
DECLARE error int DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET error = 1;
START TRANSACTION;
insert into t_test (`name`,`job`,`add_time`) VALUES (name,job,add_time);
IF (error = 1) THEN
     ROLLBACK;
     SET back = 0;
ELSE
     COMMIT;
    SET back = 1;
    END IF;
END //
将判断写在事务中

相关文章:

  • 2022-12-23
  • 2021-11-12
  • 2021-09-25
  • 2021-07-07
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-02-11
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案