当前位置:   article > 正文

mysql 事务 rollback失效 回滚无效_mysql rollback失效

mysql rollback失效

失效的几种原因:

一、数据库或者数据表的存储引擎不是Innodb

 数据库与表的存储引擎必须是Innodb;因为这个存储引擎才支持事务;

二、使用 出错时跳过错误(DECLARE CONTINUE HANDLE FOR SQLEXCEPTION),却没有把自动提交关闭。如果使用出错跳出(DECLARE EXIT HANDLE FOR SQLEXCEPTION),则不需要关闭自动提交。

在开启事务时一定要把 autocommit 自动提交关闭 (set @@autocommit = 0);关闭当前会话自动提交功能,在Commit/Rollback后再打开(看你的需求,一般来说是要打开的,否则会影响其他业务的执行);

三、事务中间使用非DML语言导致Rollback无效。Rollback只能回滚DML语言。比如使用truncate清空表格将无法逆转,无法回滚。在事务中一定不能使用非DML 语言.

四、innodb_rollback_on_timeout = off 也可能导致 回滚失效 设置为 on

五、一般来说,如果存储过程出现了错误,就不要继续执行了。就像程序出错一样,出错了就不再往下执行。所以推荐EXIT来处理回滚。

  1. DECLARE EXIT HANDLER for SQLEXCEPTION
  2. begin
  3. set t_error = 1;
  4. ROLLBACK;
  5. end;

而非 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION 去处理回滚,如果使用 CONTINUE 请参考第二条。

 

如果使用 DECLARE CONTINUE HANDLE FOR SQLEXCEPTION 处理 则可能遇到的跟我同一个问题,请看下面。

着重讲下为什么自动提交会导致Rollback失效呢?今天我可是吃了这个大亏,记录一下!

上图:

首先启动两个会话,我的事务等级是串行化

第一步第一个会话输入指令;

start transaction;

select * from test;

没有问题完美执行;

第二步第二个会话输入指令;

start transaction;

select * from test;

完美执行;

第三步第一个会话输入指令;

insert into test values('a',1);

出现等待,第二个会话也在使用test表,等待第二个会话的释放

第四步第二个回话输入指令;

insert into test values('b',1);

这时候直接报错->fuck,叫我重新开启事务,第一回话这时候运行通过;

第五步,第一个会话中输入指令;

insert into test values('a',2);

insert into test values('a',3);

rollback;

都完美运行,

第六步,第二个会话中输入指令;

insert into test values('b',2);

insert into test values('b',3);

rollback;

也完美运行;

接下来

select * from test;

我艹,

有两条记录,说明第二个会话中的rollback 未能得到运行;

分享原因,

在会话2报错后,前面的insert被回滚了;这时候事务被终止;

由于开启了自动提交

insert into test values('b',2);

insert into test values('b',3);

被自动提交了;

后面的rollback未起到作用;

 

在开启事务时自动提交会被禁用,当事务终止后自动提交又被开启!被坑的好惨...

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/992179
推荐阅读
相关标签
  

闽ICP备14008679号