声明式事务
开启事务
- 使用@EnableTransactionManagement注解,开始事务管理
- 使用@Transactional注解,给对应的方法或类创建事务
声明式事务是通过AOP的CGLib代理,例如添加一个DataSourceTransactionManager事务管理对象完成。
事务回滚注意事项
在逻辑上要保证原子性,要么同时成功,要么同时失败时,此时就需要开启事务;注意需要数据库支持事务;事务默认状态一般是默认自动提交的;
对于被@Transactional注解表明,当前处在同一个事务,出现异常时回回滚,注意需要指定rollbackFor需要回滚的异常,避免本来出现哪些自定义异常需要回滚但没有指定的情况出现;
除了需要指定异常以外,还有事务的传播行为需要注意,多个事务间的处理方式;以及隔离级别;
声明式事务失效的几种情况
- 直接调用方法,会导致事务失效(同类,不同类)
/**
* 1. 无论b是否出现异常,b的Transactional都不会生效
* 2. a的Transactional只有在a方法向外抛出异常时会生效,此时b的也会回滚
*/@Transactional(rollbackFor=Throwable.class)xpublicvoida(){b()}@Transactional(rollbackFor=Throwable.class)publicvoidb(){// do something...}
- 调用DDL会导致事务提交
真实踩过的坑,DDL会自动提交事务,比如Truncate table table_name会将当前事务提交,也就是事务失效
- 注意事务的传播行为,PROPAGATION_SUPPORTS、PROPAGATION_NOT_SUPPORTED、PROPAGATION_NEVER也会导致事务失效
- protected、private 修饰的方法上使用 @Transactional 注解,事务会失效
总结:声明式事务,只需要关注被声明的方法是否有异常抛出,有则回滚,没有则自动提交(如被catch到异常不抛出,则不会回滚)