Spring事务的了解
基于 @Transactional 的声明式事务管理
添加事务管理
Spring为了支持事务管理,专门封装了事务管理对象。
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,因为,Spring只提供统一事务管理接口,具体实现都是由各数据库自己实现,数据库事务的提交和回滚是通过 redo log 和 undo log实现的。Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。
可回答:Spring 的声明式事务管理是通过AOP技术实现的事务管理,其本质是对目标方法进行前后拦截,然后在目标方法执行之前创建或者加入一个事务,在目标方法执行完成后根据目标方法的执行情况进行事务提交或者回滚。
声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过**@Transactional注解的方式,便可以将事务规则应用到业务逻辑中,减少业务代码的污染。唯一不足地方是,最细粒度只能作用到方法级别**,无法做到像编程式事务那样可以作用到代码块级别。
Spring事务的种类:
spring支持编程式事务管理和声明式事务管理两种方式:
①编程式事务管理使用TransactionTemplate。
②声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前启动一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
扩展:
在Spring容器中添加事务管理的配置:
1 | <!-- 配置Spring提供的事务管理器 --> |
在Service组件中,使用@Transactional注解,就可以给业务方法添加事务管理。
1 |
|
注意:
- 需要事务管理的service,在方法上加上@Transactional 注解即可。
- 必须为public方法才行,不要捕捉异常,要让异常自动抛出,否则不能进行事务回滚。
事务传播行为
含义:
spring事务的传播机制说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。事务传播机制实际上是使用简单的ThreadLocal实现的,所以,如果调用的方法是在新线程调用的,事务传播实际上是会失效的。
事务传播行为就是多个事务方法调用时,如何定义方法间事务的传播。
@Transactional 注解中的 propagation 属性,可以设置事务传播行为。属性值为:
- REQUIRED(默认值):如果当前没有事务,就新建一个事务,如果已经存在一个事务中,就加入到这个事务中。这是最常见的选择。
- SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
- MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
- REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
- NOT_SUPPORTED:以非事务方式执行操作,如果存在事务,就把当前事务挂起。
- NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
Spring中的隔离级别:
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,允许事务在执行过程中,读取其他事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,允许事务在执行过程中,读取其他事务已经提交的数据。
④ ISOLATION_REPEATABLE_READ:可重复读,在同一个事务内,任意时刻的查询结果都是一致的。
⑤ ISOLATION_SERIALIZABLE:所有事务逐个依次执行。