我在spring中使用@Transactional标注后,发现并没有效果,多方求解最终找出原因。以下是一些使用此标签的注意事项,如果不按这些规矩来就会失效:
1、在Spring启动项中开启事务
@EnableTransactionManagement
2、@Transactional只作用于public方法上,如果方法是private等其他作用域就不起作用
3、如果@Transactional没有指定回滚的异常,就只针对RuntimeException,非RuntimeException不能回滚,如需避免就指定回滚异常如@Transactional(rollbackFor = Exception.class)
4、@Transactional只作用于Spring的bean的一级方法,如果在子方法上标注@Transactional则无效,原因是Spring AOP 代理方式,不会代理子方法上的事物,解决方式是暴露代理的真实类然后执行子方法((ReaderServiceImpl)AopContext.currentProxy()).borrowBooks();
再次运行,如果没有添加expose-proxy=”true”这个属性,则会报错
java.lang.IllegalStateException: Cannot find current proxy: Set ‘exposeProxy’ property on Advised to ‘true’ to make it available.
所以,需要在启动项上开启@EnableAspectJAutoProxy(exposeProxy = true,proxyTargetClass = true)
5、注意数据库引擎是否支持事物,比如mysql的MyISAM
6、try catch结构中如果有finally,即便是在catch中throw了exception,也不会触发事物回滚