Spring事务的使用及注意事项
一、注意事项
不要在接口上声明@Transactional,而要在具体类的方法上使用 @Transactional 注解,否则注解可能无效。
不要图省事,将@Transactional放置在类级的声明中,放在类声明,会使得所有方法都有事务。故@Transactional应该放在方法级别,不需要使用事务的方法,就不要放置事务,比如查询方法。否则对性能是有影响的。
@Transactional 的事务开启 ,或者是基于接口的 或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的 。
用REQUIRES_NEW的时候,发现没有起作用
分析了一下,原因是A方法(有事务)调用B方法(要独立新事务),如果两个方法写在同一个类里,spring的事务会只处理能同一个。解决方案1:需要将两个方法分别写在不同的类里。 解决方案2:方法写在同一个类里,但调用B方法的时候,将service自己注入自己,用这个注入对象来调用B方法。
使用了@Transactional的方法,只能是public,@Transactional注解的方法都是被外部其他类调用才有效,故只能是public。道理和上面的有关联。故在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错,但事务无效。
默认只有RuntimeExcetion会触发回滚,经验证明确实如此,所以rollbackFor可以自行设置如下:rollbackFor = {Exception.class},当然具体业务具体处理,可能有的业务抛出的某些异常并不需要触发回滚,所以此时应该细化处理异常。
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor={/*自定义Exception,可以是多个*/ IOException.class})
上面的这个rollbackFor配置,可以理解为:当配置这个事务的方法内返回了IOException,则会触发回滚操作。
MySQL数据库表引擎应为InnoDB,否则不支持事务。