@Transactional注解使用注意
- 必须用在public方法上。如果使用在别的方法上(比如protected,private)不会报错,但是事务不会生效
- 要在类方法上使用该注解(注解不能被继承),可以在接口上使用,但是需要配置相应的接口代理,所以不推荐在接口上使用
- 不要图省事,将注解放在类上声明,会使所有方法都有事务,为了性能考虑,最好的使用方式是在接口上使用
- 同类方法中调用(注解在类上),事务不生效;同样,A调B方法,B有A没有,事务同样不生效
- spring事务在抛异常的时候会回滚,但如果catch捕获了,事务无效。可以在catch加throw new RuntimeException
- 最后有个关键的一点:和锁同时使用需要注意:由于Spring事务是通过AOP实现的,所以在方法执行之前开启事务,之后提交事务逻辑。而synchronized代码块执行是在事务之内执行的,可以推断在synchronized代码块执行完时,事务还未提交,这时其他线程进入synchronized代码块后,读取的数据不是最新的。所以必须使synchronized锁的范围大于事务控制的范围,把synchronized加到Controller层或者
大于事务控制的范围,把synchronized加到Controller层或者大于事务边界的调用层
@Transactional注解属性
-
@Transactional(readOnly = true) 设置当前事务为只读。默认为false
-
@Transactional(rollbackFor = {RuntimeException.Class,…})
设置出现数组中异常后回滚,noRollbackFor属性中则设置的是不需要回滚的异常类 -
@Transactional(rollbackForClassName = {“RuntimeException”,…})
设置出现需要回滚的异常数组,参数类型为String。同样NoRollbackForClassName是不需要回滚的异常类名 -
@Transactional(progation = Propagation.NOT_SUPPORTED)
设置传播行为 -
@Transactional(isolation = Isolation.REPEATABLE_READ,rollbackFor = RuntimeException.class)
设置隔离级别 -
@Transactional(timeout = -1)
设置事务超时时间,-1为永不超时