当前位置:网站首页>事务回滚异常
事务回滚异常
2022-07-05 15:26:00 【小蚂蚁hjk】
org.springframework.transaction.UnexpectedRollbackException
Spring事务传播机制汇总如下:
- PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务,就加入到这个事务中。默认策略
- PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
nested 的子异常抛出 如果被catch 外部插入成功
nested 的子异常抛出 如果不被catch 外部插入失败
nested外面异常抛出 nest内部插入成功 nest也会跟着回滚
spring事务默认的传播行为:
@Transactional 等于 @Transactional(propagation=Propagation.REQUIRED)
发生异常的场景描述:
在使用Spring事务时,在一个事务A中又开了一个事务B(即存在嵌套事务),当事务B发生异常时,将异常catch后事务B会进行回滚操作,若此时异常被直接吃掉(即事务A无法得知发生过异常),则事务A会抛出如上异常。
例如:
serviceA有事务 @Transactional
serviceB有事务 @Transactional
serviceA.methodA()
{
doSomethingA();
try {
serviceB.methodB{}; //这里面有异常标记为回滚, doSetRollbackOnly(status);
}
catch {
//捕获异常转到commit时,由于已经标记为要回滚, 回滚并抛出新异常
}
doSomethingB();
}
原因:
因为methodB的传播属性设置为PROPAGATION_REQUIRED,PROPAGATION_REQUIRED的意思是,当前有事务,则使用当前事务,当前无事务则创建事务。由于methodA的传播属性也为PROPAGATION_REQUIRED,所以methodA会创建一个事务,然后methodB与methodA使用同一个事务,methodB出现异常后,将当前事务标志位回滚,由于在methodA中做了trycatch处理,程序没有终止而是继续往下走,当事务commit时,check状态,发现,需要事务回滚,所以才会出现不可预知的事务异常:因为事务被标志位回滚,所以事务回滚。
也就是说:methodA与methodB共用一个事务,methodB将事务标志为回滚,methodA中commit这个事务,然后,出现事务已经被标志回滚(methodB标志的)的异常信息。
解决方案
情况1:methodA与methodB在逻辑上不应该属于同一个事务,那么将methodB的事务传播属性修改为PROPAGATION_REQUIRES_NEW,这样,执行methodB时,会创建一个新的事务,不影响methodA中的事务。
情况2:业务A与业务B在业务逻辑上就应该属于同一个事务,那么将methodA中的try catch去掉
情况3:业务A与业务B在业务逻辑上就应该属于同一个事务,但是methodB的失败与否不能影响methodA的事务提交,那么仍然在methodA中try catch methodB,并将methodB设置为PROPAGATION_NESTED,它的意思是,methodB是一个子事务,有一个savepoint,失败时会回滚到savepoint,不影响methodA,如果成功则A、B一起提交,A与B都是一个事务,只是B是一个子事务。
情况4:业务A 有无事务无影响 去掉业务A的@Transactional
小结:
- 深入理解事务传播的各个状态含义,比如PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_MANDATORY、PROPAGATION_REQUIRES_NEW等
- 最初我以为是由于spring配置文件中,methodA的事务设置为ready-only=true(只读事务)的原因,经过查询资料得知,只读事务与事务传播不冲突,是两个机制。只读事务,是一个特殊的事务,该事务内,只能是查询语句,不能含有修改、更新语句,数据库可能对只读事务做优化;传播属性是母方法与子方法之间的关系表达。
- 注意,同一个类中,事务嵌套以最外层的方法为准,嵌套的事务失效;不同类中嵌套的事务才会生效;
边栏推荐
- Detailed explanation of QT creator breakpoint debugger
- OceanBase社区版之OBD方式部署方式本地安装
- Common MySQL interview questions (1) (written MySQL interview questions)
- 20.[STM32]利用超声波模块和舵机实现智能垃圾桶功能
- 定义严苛标准,英特尔Evo 3.0正在加速PC产业升级
- Data communication foundation ACL access control list
- Bugku easy_ nbt
- MySQL giant pit: update updates should be judged with caution by affecting the number of rows!!!
- P1451 calculate the number of cells / 1329: [example 8.2] cells
- MySQL overview
猜你喜欢

Data communication foundation - dynamic routing protocol rip
![17.[STM32]仅用三根线带你驱动LCD1602液晶](/img/c6/b56c54da2553a451b526179f8b5867.png)
17.[STM32]仅用三根线带你驱动LCD1602液晶

Good article inventory

lvgl 显示图片示例

Data communication foundation smart_ Link_&_ Monitor_ Link

OceanBase社区版之OBD方式部署方式本地安装

Object. defineProperty() - VS - new Proxy()

I spring and autumn blasting-2

Information collection of penetration test

Usage and usage instructions of JDBC connection pool
随机推荐
Detailed explanation of C language branch statements
Example of lvgl display picture
D-snow halo solution
lv_font_conv离线转换
Li Kou today's question -729 My schedule I
Bugku's Ah Da
Analytic hierarchy process of mathematical modeling (including Matlab code)
OceanBase社区版之OBD方式部署方式本地安装
助力数字经济发展,夯实数字人才底座—数字人才大赛在昆成功举办
Lesson 4 knowledge summary
Data communication foundation - dynamic routing protocol rip
How difficult is it to pass the certification of Intel Evo 3.0? Yilian technology tells you
20.[STM32]利用超声波模块和舵机实现智能垃圾桶功能
Arduino controls a tiny hexapod 3D printing robot
vlunhub- BoredHackerBlog Social Network
Noi / 1.3 01: a+b problem
Bugku easy_ nbt
Aike AI frontier promotion (7.5)
P6183 [USACO10MAR] The Rock Game S
17.[STM32]仅用三根线带你驱动LCD1602液晶