当前位置: 首页 > 编程笔记 >

java事务回滚失败问题分析

姚棋
2023-03-14
本文向大家介绍java事务回滚失败问题分析,包括了java事务回滚失败问题分析的使用技巧和注意事项,需要的朋友参考一下

Spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。

一切还是要从Java的检查型异常和非检查型异常说起。

那么什么是检查型异常什么又是非检查型异常呢?

最简单的判断点有两个:

1.继承自RuntimeException或Error的是非检查型异常,而继承自Exception的则是检查型异常(当然,RuntimeException本身也是Exception的子类)。

2.对非检查型类异常可以不用捕获,而检查型异常则必须用try……catch语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它。

Java的异常结构如下图。其中直接继承Exception的异常,必须捕获,属于检查型异常。

再回过来看我的代码:

1、方法名前面有

@Transactional 

2、Spring的配置文件applicationContext-XXX.xml当中也有Spring事物的相关配置

<bean id="transactionManager" 
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
  <property name="dataSource" ref="dataSource" /> 
  <property name="rollbackOnCommitFailure" value="true"></property> 
</bean> 

但是为什么在Service层方法调用的时候,try……catch抛Exception异常已经提交的事物却没有回滚?

查看相关spring的文档后发现,原来spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

代码中try……catch抛出的Exception异常,属于检查型异常,Spring的框架默认是不会进行回滚的。

在编程中对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。

所以必须在service捕获异常,然后再次手动throw一个非检查型异常,这样事务方才起效。例如:

try{ 
  ………… 
} catch (Exception e) { 
  ………… 
  throw new BusinessException(e.getMessage()); 
} 

当然我们还有更简便的方法来解决这个问题,那就是通过注解参数改变默认的回滚方式。

在@Transaction注解中定义了noRollbackFor和RollbackFor来指定某种异常是否回滚。

使用例:

@Transaction(noRollbackFor=RuntimeException.class)

@Transaction(RollbackFor=Exception.class)

所以上述的问题可以直接将@Transaction添加回滚参数@Transaction(RollbackFor=Exception.class),这样就改变了默认的事务处理方式。

启示:

这就要求我们在自定义异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。

总结

以上就是本文关于java事务回滚失败问题分析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

 类似资料:
  • 我列出了一个问题“Spring事务失败回滚”。我有一个服务类,它调用2 DAO将数据插入到数据库表中。 我的事务配置: 我的服务和dao定义如下:

  • 总之,我在使用Spring Batch CompositeItemWriter时遇到了事务回滚问题。Spring batch的版本为2.2.7。 我的配置与此处的帖子相同:https://stackoverflow.com/questions/32432519/compositeitemwriter-doesnt-roll-back-in-spring-batch 当第三个ItemWriter抛出

  • 让我们想象一下这种情况,然后我们在微服务中使用SAGA方法管理分布式事务。 失败的场景: < li >服务A成功完成任务,并将消息发送给服务B < li >服务B成功完成任务,并将消息发送到服务C < li >服务C失败,并向服务B发送消息以撤消交易。 < li >服务B尝试撤消交易但失败。 因此,我们有不一致的数据,这是不可接受的。问题是,SAGA模式下事务回滚失败的情况如何处理?

  • 本文向大家介绍.NET framework 4.0 安装失败回滚问题,包括了.NET framework 4.0 安装失败回滚问题的使用技巧和注意事项,需要的朋友参考一下   根据微软论坛作者的英文解释,.NET framework 4.0 安装失败回滚貌似是因为“msvcr100_clr0400.dll”文件不能被覆盖的原因导致的,那么问题就简单了,我们只要把C盘下面的两个文件重命名就ok了。

  • 我有Spring > 不应该失败主事务,在我的例子中是cteateSmth() 如果失败,应该回滚它自己的事务 service1.cteatsmth(); 在上面的例子中,即使尝试对cretePartA()进行捕获包装,整个cteateSmth()事务也将回滚。 我尝试使用REQUIRES_NEW来实现这一点,但在这种情况下似乎无法回滚cretePartA()操作。 我试图不为cretePartA

  • 问题是,即使在为Exception.class声明回滚之后,事务仍然没有回滚。 1.我的数据源