@Transactional注解实现和编码实现的选择。
二者控制的粒度不同,@Transactional的粒度是类或者方法级别。编码实现可以控制到更细粒度级别。
一、使用方式@Transactional注解可以使用在接口、类、类方法上。
- 作用于类:该类及其子类下的所有public 方法都配置了相同的事务属性信息。
- **作用于类方法:**当类配置了@Transactional,方法上配置的@Transactional注解覆盖类上注解属性信息。
- 作用于接口: 不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效。(@Transactional是通过代理对象实现的,CGLib只能代理类不能代理接口)。
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是通过spring代理对象实现的。
(二)@Transactional 注解属性 propagation 设置错误这种失效是由于配置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。
- TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
- TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
- TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
rollbackFor 可以指定能够触发事务回滚的异常类型。不设置,默认只会在RuntimeException异常和Error异常才会回滚。
一般需要设置为java.lang.Exception异常。
(四) 同一个类中方法调用,导致失效同一个类中,有a方法、b方法。a方法调用b方法,a方法没有事务,b方法有事务,a方法调用b方法。外部类调用a方法时,b方法的事务不会生效。
原因:由于sprngAOP代理造成的,因为只有当事务方法被类以外的代码调用时,才会由Spring生成的代理对象来管理。
(五) 异常被cach掉,导致失效此时不会回滚事务,但是会抛出一个UnexpectedRollbackException异常。
业务方法中yaocach,需要指定throw 异常。
(六) 数据库引擎不支持myisam引擎不支持事务。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)