在Spring中,数据库事务是通过AOP技术来提供服务的。在JDBC中存在着大量的try....catch...finally...语句,也同时存在着大量的冗余代码,如那些打开和关闭数据库连接的代码以及事务回滚的代码。使用Spring AOP后,Spring将它们擦除了,你将看到更为干净的代码,没有那些try...catch...finally...语句,也没有大量的冗余代码。
Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种。
编程式事务:是指在代码中手动的管理事务的提交、回滚等操作,代码侵入性比较强
声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。声明式事务也有两种实现方式,一是基于TX和AOP的xml配置文件方式,二种就是基于@Transactional注解了。
对于一些业务网站而言,产品库存的扣减、交易记录以及账户都必须是要么同时成功,要么同时失败,这便是一种事务机制,对于这样的机制数据库给予了支持。
而在一些特殊的场景下,如一个批处理,它将处理多个交易,但是在一些交易中发生了异常,这个时候则不能将所有的交易都回滚。
如果所有的交易都回滚,那么那些本能够正常处理的业务也无端地被回滚了,这显然不是我们所期待的结果。通过Spring的数据库事务传播行为,可以很方便地处理这样的场景。
propagation属性
propagation 代表事务的传播行为,默认值为 Propagation.REQUIRED,其他的属性信息如下:
Propagation.REQUIRED:如果当前存在事务,则加入该事务,如果当前不存在事务,则创建一个新的事务。( 也就是说如果A方法和B方法都添加了注解,在默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 )
Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行。
Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常。
Propagation.REQUIRES_NEW:重新创建一个新的事务,如果当前存在事务,暂停当前的事务。( 当类A中的 a 方法用默认Propagation.REQUIRED模式,类B中的 b方法加上采用 Propagation.REQUIRES_NEW模式,然后在 a 方法中调用 b方法操作数据库,然而 a方法抛出异常后,b方法并没有进行回滚,因为Propagation.REQUIRES_NEW会暂停 a方法的事务 )
Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。
Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。Propagation.NESTED :和 Propagation.REQUIRED 效果一样。
又如异常类型,从而确定方法发生什么异常下回滚事务或者发生什么异常下不回滚事务等
如果发生异常,就要判断一次事务定义器内的配置,如果事务定义器已经约定了该类型的异常不回滚事务就提交事务,如果没有任何配置或者不是配置不回滚事务的异常,则会回滚事务,并且将异常抛出,这步也是由事务拦截器完成的。
@Transactional注解的失效场景_dianxiaoer20111的博客-CSDN博客_@transactional rollbackfor