事务注解@Transactional详解
@Transactional 是声明式事务管理 编程中使⽤的注解
1 .添加位置
1)接⼝实现类或接⼝实现⽅法上,⽽不是接⼝类中。
2)访问权限:public 的⽅法才起作⽤。@Transactional 注解应该只被应⽤到 public ⽅法上,这是由 Spring AOP 的本质决定的。
系统设计:将标签放置在需要进⾏事务管理的⽅法上,⽽不是放在所有接⼝实现类上:只读的接⼝就不需要事务管理,由于配置了
@Transactional就需要AOP拦截及事务的处理,可能影响系统性能。
3)错误使⽤:
1.接⼝中A、B两个⽅法,A⽆@Transactional标签,B有,上层通过A间接调⽤B,此时事务不⽣效。
2.接⼝中异常(运⾏时异常)被捕获⽽没有被抛出。
默认配置下,spring 只有在抛出的异常为运⾏时 unchecked 异常时才回滚该事务,
也就是抛出的异常为RuntimeException 的⼦类(Errors也会导致事务回滚),
⽽抛出 checked 异常则不会导致事务回滚 。可通过 @Transactional rollbackFor进⾏配置。
3.多线程下事务管理因为线程不属于 spring 托管,故线程不能够默认使⽤ spring 的事务,
也不能获取spring 注⼊的 bean 。
在被 spring 声明是事务管理的⽅法内开启多线程,多线程内的⽅法不被事务控制。
⼀个使⽤了@Transactional 的⽅法,如果⽅法内包含多线程的使⽤,⽅法内部出现异常,
不会回滚线程中调⽤⽅法的事务。
spring aop应用场景
2.声明式事务管理实现⽅式:
MyBatis ⾃动参与到 spring 事务管理中,⽆需额外配置,
只要 batis.spring.SqlSessionFactoryBean 引⽤的数据源与
DataSourceTransactionManager 引⽤的数据源⼀致即可,否则事务管理会不起作⽤。
<annotation-driven> 标签的声明,
是在 Spring 内部启⽤ @Transactional 来进⾏事务管理,使⽤ @Transactional 前需要配置。
事务的隔离级别
事务的隔离级别:是指若⼲个并发的事务之间的隔离程度
1.@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读,不可重复读) 基本不使⽤
2.@Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
3.@Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
4.@Transactional(isolation = Isolation.SERIALIZABLE):串⾏化
事务传播⾏为:如果在开始当前事务之前,⼀个事务上下⽂已经存在,此时有若⼲选项可以指定⼀个事务性⽅法的执⾏⾏为事务传播⾏为
1. TransactionDefinition.PROPAGATION_REQUIRED:
如果当前存在事务,则加⼊该事务;如果当前没有事务,则创建⼀个新的事务。这是默认值。
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:
创建⼀个新的事务,如果当前存在事务,则把当前事务挂起。
3. TransactionDefinition.PROPAGATION_SUPPORTS:
如果当前存在事务,则加⼊该事务;如果当前没有事务,则以⾮事务的⽅式继续运⾏。
4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。
5. TransactionDefinition.PROPAGATION_NEVER:
以⾮事务⽅式运⾏,如果当前存在事务,则抛出异常。
6. TransactionDefinition.PROPAGATION_MANDATORY:
如果当前存在事务,则加⼊该事务;如果当前没有事务,则抛出异常。
7. TransactionDefinition.PROPAGATION_NESTED:
如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;
如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
字段说明:
1. value :主要⽤来指定不同的事务管理器;
主要⽤来满⾜在同⼀个系统中,存在不同的事务管理器。
⽐如在Spring中,声明了两种事务管理器txManager1, txManager2.然后,
⽤户可以根据这个参数来根据需要指定特定的txManager.
2. value 适⽤场景:在⼀个系统中,需要访问多个数据源或者多个数据库,
则必然会配置多个事务管理器的
3. REQUIRED_NEW:内部的事务独⽴运⾏,在各⾃的作⽤域中,可以独⽴的回滚或者提交;  ⽽外部的事务将不受内部事务的回滚状态影响。
4. ESTED 的事务,基于单⼀的事务来管理,提供了多个保存点。
这种多个保存点的机制允许内部事务的变更触发外部事务的回滚。
⽽外部事务在混滚之后,仍能继续进⾏事务处理,即使部分操作已经被混滚。
由于这个设置基于 JDBC 的保存点,所以只能⼯作在 JDB C的机制。
5. rollbackFor:让受检查异常回滚;即让本来不应该回滚的进⾏回滚操作。
6. noRollbackFor:忽略⾮检查异常;即让本来应该回滚的不进⾏回滚操作。