MySql存储过程捕获异常回滚

DROP PROCEDURE IF EXISTS pro_test;
CREATE PROCEDURE pro_test
(
    para_a varchar(50),
    para_b varchar(50)
)
BEGIN
    DECLARE result_code INTEGER DEFAULT 0; -- 定义返回结果并赋初值0
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET result_code=1; -- 在执行过程中出任何异常设置result_code为1
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET result_code = 2; -- 如果表中没有下一条数据则置为2

    START TRANSACTION; -- 开始事务
    /*
    * 这里写具体的业务处理...
    * 业务处理过程中可以根据实际情况自定义result_code
    */
    IF result_code = 1 THEN -- 可以根据不同的业务逻辑错误返回不同的result_code,这里只定义了1和0
        ROLLBACK; 
    ELSE 
        COMMIT; 
    END IF;
SELECT result_code;
END

代码如上所示

这里补充一点作者也是刚刚才了解到的一点知识:

如果事务中所有sql语句执行正确则需要自己手动提交commit;否则有任何一条执行错误,需要自己提交一条rollback,这时会回滚所有操作,否则在出错的sql语句前面正确的sql语句会在下次执行了一条commit 或begin或start transaction(新开一个事务会将该链接中的其他未提交的事务提交,相当于commit!)时提交运行。

具体看代码:

DROP PROCEDURE IF EXISTS `PRO2`;

CREATE DEFINER = `root`@`localhost` PROCEDURE `PRO2`()
BEGIN
    DECLARE t_error INTEGER default 0;
    DECLARE    CONTINUE HANDLER FOR SQLEXCEPTION SET t_error = 1;

    START TRANSACTION;
        INSERT INTO test VALUES    (1, '2'); #1
        INSERT INTO test VALUES    (1, '3'); #2
        IF t_error = 1 THEN
            #ROLLBACK; #3
        ELSE
            COMMIT;
        END IF;
END;

如上面的代码,#1和#2由于主键冲突,所以会报错。

如果这时#3的ROLLBACK语句被注释掉,然后把#1和#2换为:

INSERT INTO test VALUES    (2, '2');
INSERT INTO test VALUES    (3, '3');

再运行一次,你会发现test表里除了id=2,id=3的行外,还有一条id=1的记录。

这就是遇到错误没有回滚,已经正确执行的sql语句会在下次commit时被再次提交。

所以,上面的#3里的ROLLBACK一定要注意加上。

好吧,虽然知道大家都对ROLLBACK印象深刻,不会犯这种错误,但作者觉得 已经正确执行的sql语句在遇到错误后,会在下次遇到commit时被再次提交  ,这个点作者也忽略了,所以自己记录一下。

看到的童鞋不喜勿喷哈!

参考:

MySql存储过程捕获异常回滚

对mysql事务提交、回滚的错误理解

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值