声明式事务:基于AOP面向切面的,它将具体业务与事务处理部分解耦,代码侵入性很低,所以在实际开发中声明式事务用的比较多。声明式事务也有两种实现方式,一是基于TX和AOP的xml配置文件方式,二种就是基于@Transactional注解了。
1、@Transactional注解可以作用于哪些地方?
@Transactional 可以作用在接口、类、类方法。
作用于类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息。
作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
作用于接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失
2、当@Transactional不起作用时:
1、首先要看数据库本身对应的库、表所设置的引擎是什么。MyIsam不支持事务,如果需要,则必须改为InnnoDB。
2、@Transactional所注解的方法是否为public
如果应用在protected、private或者 package可见度的方法上,也不会报错,不过事务设置不会起作用。
3、@Transactional所注解的方法所在的类,是否已经被注解@Service或@Component等。
4、需要调用该方法,且需要支持事务特性的调用方是在在 @Transactional所在的类的外面。注意:类内部的其他方法调用这个注解了@Transactional的方法,事务是不会起作用的。
注意:service类标签(一般不建议在接口上)上添加@Transactional,可以将整个类纳入spring事务管理,在每个业务方法执行时都会开启一个事务,不过这些事务采用相同的管理方式。
5、注解为事务范围的方法中,事务的回滚仅仅对于unchecked的异常有效。对于checked异常无效。也就是说事务回滚仅仅发生在出现RuntimeException或Error的时候。
那么什么是checked异常,什么是unchecked异常
java里面将派生于Error或者RuntimeException(比如空指针,1/0)的异常称为unchecked异常,其他继承自java.lang.Exception得异常统称为Checked Exception,如IOException、TimeoutException等
6、@Transactional 注解属性 propagation 设置错误,若是错误的配置以下三种 propagation,事务将不会发生回滚。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
7、多数据源的情况下需要指定事务管理器
配置多个事务
@Bean(name = "accountTransactionManager")
@Primary
public PlatformTransactionManager testTransactionManager(@Qualifier("accountDataSource") DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
指定事务
@Override
@Transactional(value = "accountTransactionManager",rollbackFor = Exception.class)
public boolean insertAddMoney(String account, String quota) {
...
}
参考