事务和@Transactional的理解

事务和@Transactional的理解

@Transactional注解实现和编码实现的选择。

二者控制的粒度不同,@Transactional的粒度是类或者方法级别。编码实现可以控制到更细粒度级别。

一、使用方式

@Transactional注解可以使用在接口、类、类方法上。

  • 作用于类:类及其子类下的所有public 方法都配置了相同的事务属性信息。
  • **作用于类方法:**当类配置了@Transactional,方法上配置的@Transactional注解覆盖类上注解属性信息。
  • 作用于接口: 不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效。(@Transactional是通过代理对象实现的,CGLib只能代理类不能代理接口)。

二、@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:默认。这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
  • Isolation.READ_UNCOMMITTED:读未提交。这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
  • Isolation.READ_COMMITTED:读已提交。保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
  • Isolation.REPEATABLE_READ:可重复读。这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读。
  • Isolation.SERIALIZABLE:序列化(串行化)。这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。

三、@Transactional失效场景

(一) 应用在非public修饰的方法上,@Ttransational将会失效。

失效原因: @Transactional是通过spring代理对象实现的。

(二)@Transactional 注解属性 propagation 设置错误

这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。

  • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。

(三) @Transactional 注解属性 rollbackFor 设置错误

rollbackFor 可以指定能够触发事务回滚的异常类型。不设置,默认只会在RuntimeException异常和Error异常才会回滚。

一般需要设置为java.lang.Exception异常。

(四) 同一个类中方法调用,导致失效

同一个类中,有a方法、b方法。a方法调用b方法,a方法没有事务,b方法有事务,a方法调用b方法。外部类调用a方法时,b方法的事务不会生效。

原因:由于sprngAOP代理造成的,因为只有当事务方法被类以外的代码调用时,才会由Spring生成的代理对象来管理。

(五) 异常被cach掉,导致失效

此时不会回滚事务,但是会抛出一个UnexpectedRollbackException异常。

业务方法中yaocach,需要指定throw 异常。

(六) 数据库引擎不支持

myisam引擎不支持事务。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值