@Transactional知识总结

@Transactional 可以作用在接口、类、类方法

  • 作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。
  • 作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
  • 作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效

@Transactional注解属性

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 效果一样。

isolation :事务的隔离级别,默认值为Isolation.DEFAULT。

  • Isolation.DEFAULT:使用底层数据库默认的隔离级别。
  • Isolation.READ_UNCOMMITTED:读未提交
  • Isolation.READ_COMMITTED:读已提交
  • Isolation.REPEATABLE_READ:可重复读
  • Isolation.SERIALIZABLE:串行化

timeout :事务的超时时间,默认值为 -1。如果超过该时间限制但事务还没有完成,则自动回滚事务。

readOnly :指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。

rollbackFor :用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。当我们直接使用@Transactional不指定rollbackFor时,默认会回滚运行时异常及其子类,也就是RuntimeException及其子类,如果发生了Exception异常就不会回滚,因为Exception是RuntimeException的父类。

  • RuntimeExceptionException是Java中两种不同类型的异常。RuntimeException是一种未检查异常(unchecked exception),它通常是由于程序中的逻辑错误导致的,例如空指针异常(NullPointerException)或数组越界异常(ArrayIndexOutOfBoundsException)。这类异常在编译时不需要被显式地捕获或声明,因为它们通常是可以避免的,如果出现了这类异常,通常意味着程序中存在bug。
  • 相比之下,Exception是一种已检查异常(checked exception),它通常表示程序运行时可能遇到的外部问题,如文件无法读取(IOException)或数据库连接失败(SQLException)。这类异常在编译时必须被处理,要么通过try-catch语句块捕获异常,要么通过方法签名中的throws关键字声明抛出异常。

noRollbackFor:抛出指定的异常类型,不回滚事务,也可以指定多个异常类型。

javax.transaction.Transactional与org.springframework.transaction.annotation.Transactional注解的差别

  • javax.transactionorg.springframework.transaction是两个不同的事务管理接口,它们分别属于Java EE和Spring框架

  • transactionManager: Spring可以指定transactionManager,JTA不可以。

  • Isolation: Spring通过isolation属性提供了事务级别的隔离性,JTA隔离性只能控制在
    connection级别。

  • Propagation:两者都支持,Spring通过propagation指定,JTA通过value指定。Spring多了一个Nested传播类型。

  • Timeout:仅Spring支持。

  • Rollback: 都支持。 JTA通过rollbackOn和dontRollbackOn属性,Spring通过rollbackFor和noRollbackFor属性,并额外附加了2个属性rollbackForClassName和noRollbackForClassName。

@Transactional与 synchronized配合使用时遇到的问题:

  • 问题描述:当t1线程访问getCount()方法,此时他拿到synchronized的锁,在进行获取数据并且+1操作后进行update操作,此时synchronized的锁已经被释放了,但是父事务却没有提交,也就是没有写回到数据库中,接下来t2线程过来了,也拿到了这把锁,又从数据库获取了数据,此时获得的是脏数据,最后就会导致出现了相同的code。
  • 解决方法:这里是因为事务的先后提交导致,可以使用Transactional注解的配置来解决,使用@Transactional(propagation = Propagation.REQUIRES_NEW),每次都会启动一个新的事务,表示当前方法必须在自己的事务中运行,如果当前已经存在一个事务,则会挂起该事务,创建一个新的事务去执行当前方法。当当前方法执行完成后,新事务被提交,原事务恢复执行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值