? ? ? ? 我们知道,spring框架支持两种类型的事务管理,分别是编程式事务管理和声明式事务管理,声明式事务管理又支持两种方式:基于xml的声明式事务管理、基于注解的声明式事务管理。
? ? ? ? 基于注解的声明式事务管理用Transactional注解来实现,它有一些属性可以去设置,包括:事务名称、事务是否只读、事务的超时时间、事务的隔离级别、事务的传播属性、rollbackFor【遇到什么类型的异常而回滚】、noRollbackFor【忽略什么类型的异常不回滚】,我们可以通过在类上或者方法上加Transactional注解来实现声明式的事务管理,非常方便。但是使用Transactional注解也需要注意,因为使用不当会造成事务失效。
? ? ? ? 会导致Transactional注解事务失效的原因有:
? ? ? ? 1、因为Transactional注解只能在访问修饰符为public的方法上生效,所以如果我们在非public方法上使用它会导致事务失效。
? ? ? ? 2、同一个类中的不同事务方法之间的调用会导致被调用的方法事务失效。
? ? ? ? 3、当我们要调用一个事务方法时,我们应该用spring管理的一个bean去调用,而不是我们用new的方式创建的一个普通对象去调用,比如:我们在Service类中定义了一个事务方法,然后想在Controller中去调用它,那么我们应该在这个Controller中用Autowired注解或者Resource注解去注入这个Service的bean来调用,而不是new一个Service对象来调用,用我们自己new的对象去调用事务方法会导致事务失效。
? ? ? ? 4、Transactional的rollbackFor属性设置错误也有可能导致事务失效,比如,当一些不严重的异常发生时,我们并不想让事务回滚,但是rollbackFor属性我们设置的值却是Exception.class,那么一旦遇到任何异常,这个事务都会回滚,因为回滚而导致事务失效。所以我们要根据实际的业务需求去设置rollbackFor和noRollbackFor属性的值。
? ? ? ? 5、Transactional注解的传播属性设置错误也有可能导致事务失效,比如,我们将它的传播属性设置为:以非事务的方式执行,那么就会导致事务失效。
? ? ? ? 关于spring事务支持的传播属性:
? ? ? ? spring事务支持六种传播属性:
? ? ? ? 1、支持当前事务,当前有事务存在就加入这个事务,当前没有事务存在就新建一个事务。这是spring事务默认的传播属性。
? ? ? ? 2、支持当前事务,当前有事务就加入这个事务,当前没有事务,就以非事务的方式执行。
? ? ? ? 3、支持当前事务,当前有事务就加入这个事务,当前没有事务,就抛异常。
? ? ? ? 4、新建事务,当前如果有事务,就将当前存在的这个事务挂起。
? ? ? ? 5、以非事务的方式执行,当前如果有事务,就将当前的事务挂起。
? ? ? ? 6、以非事务的方式执行,当前如果有事务,就抛异常。