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来处理回滚。

DECLARE EXIT HANDLER for SQLEXCEPTION 
	begin
		set t_error = 1;
		ROLLBACK;
	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未起到作用;

 

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值