事务异常:Transaction rolled back because it has been marked as rollback-only解决方案

事务的概念

事务这个词,其实我们最先接触的地方应该是数据库,我们会知道事务有着四种特性,分别是:

  • 原子性:表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。
  • 一致性:表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。
  • 隔离性:表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。
  • 持久性:表示已提交的数据在事务执行失败时,数据的状态都应该正确。

说白了,事务也就是一组sql的指令,每个sql都是事务的一部分
假设每条sql都执行完成并且成功了,那就说明这组sql执行生效了,虽然执行了事务,但是并不影响原来sql的执行;反之如果出现了错误,那就需要事务启动了,事务会将之前的sql进行一一回滚,这条事务也就结束了,原先的sql等于都没有执行,这一组的事务执行失败

为何需要事务

体现到java中来也是一样,我们的程序有时候会不止一次的影响数据库,而如果中间有一次sql执行失败,而前面的sql已经执行,那前面的数据已经创建或者修改了,而另外一条或者多条数据依然没有发生变化,这肯定不符合正常的逻辑:哪怕报错了也不能影响其他的业务!

就像是沃兹基曾经说过:全荣才荣,一损俱损,只要有一处地方产生了错误,这一整个物件就等于坏了,雪崩的时候没有一片雪花是无辜的

而事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问

事务异常的原因

例如我们这边来看一下这个事务异常出现的原因,首先来看一下代码:
在这里插入图片描述
很好!一个大事务里面套了一个小事务,然后又用try-catch捕获小事务,导致连错误的提示都没有了,内层事务在一定场景下抛出了异常,但是却被外层事务用try–catch接住了。于是在内层事务异常的情况下,外层事务继续执行了。

如果只是没有异常提示倒还说,我们一步一步debug也能找到出错的原因,但是如果两个事务关联到了相同的表或者数据,那就容易产生一个更大的问题:lock wait timeout exceeded; try restarting transaction,也就是死锁问题,两个事务共同争取同一个资源,导致循环等待,这个问题有时间再细讲

解决方案

1、方案1(一般采用这种)

如果在确定里层方法不需要使用事务注解的话,把里层的@Transactional注解去了,因为外层本身就有事务注解,不会因为里层的方法体写到另外一个地方就不会执行事务

2、方案2

如果在确定外层事务不会修改数据库的话(例如查询),就可以去除外部的@Transactional

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值