前言
在Spring中,事务管理主要通过AOP功能实现,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,Spring支持编程式事务管理和声明式事务管理两种方式。
- 声明式事务
- @Transactional
- 编程式事务
TransactionTemplate
TransactionManager
四大特性
- 原子性(Atomicity):一个事务中的所有操作,要么都完成,要么都不执行。对于一个事务来说,不可能只执行其中的一部分。
- 一致性(Consistency):数据库总是从一个一致性的状态转换到另外一个一致性状态,事务前后数据的完整性必须保持一致。。
- 隔离性(Isolation):一个事务所做的修改在最终提交以前,对其它事务是不可见的,多个事务之间的操作相互不影响。
- 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
隔离级别
- Read Uncommitted(读取未提交内容):一个事务可以看到其他事务已执行但是未提交的结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少,并且存在脏读问题。
- Read Committed(读取已提交内容):一个事务只能看到其他事务已执行并已提交的结果(Oracle、SQL Server默认隔离级别)。这种隔离级别支持不可重复读,因为同一事务的其他实例在该实例处理期间可能会有新的commit,所以同一select可能返回不同结果。
- Repeatable Read(可重读):同一事务的多个实例在并发读取数据时,会看到同样的数据行(MySQL的默认事务隔离级别)。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC)机制解决了不可重复读问题,存在幻读问题。
- Serializable(可串行化):最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
Read Uncommitted | √ | √ | √ |
Read Committed | × | √ | √ |
Repeatable Read | × | × | √ |
Serializable | × | × | × |
传播级别
传播级别 | 含义 |
PROPAGATION_REQUIRED | 支持当前事务,如果当前没有事务,则新建一个事务 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,则以非事务进行 |
PROPAGATION_MANDATORY | 支持当前事务,如果当前没有事务,则抛异常 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,则把当前事务挂起 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果没有,则进行与PROPAGATION_REQUIRED类似操作 |
PROPAGATION_NOT_SUPPORTED | 以非事务进行,如果当前存在事务,则挂起事务,执行当前逻辑,结束后恢复上下文的事务 |
PROPAGATION_NEVER | 以非事务进行,如果当前存在事务,则抛异常 |
案例
导入相关依赖
数据源、数据库驱动、spring-jdbc模块
配置数据源
配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
数据访问
开启事务,配置事务管理器
测试类
原理
Spring 事务管理的实现原理主要涉及两个方面:事务管理器和代理机制:
- 事务管理器(Transaction Manager):
Spring通过PlatformTransactionManager接口定义了事务管理器的标准。这个接口有多个实现,包括常用的DataSourceTransactionManager、JpaTransactionManager、HibernateTransactionManager等,每个都专门用于不同的持久化技术。
事务管理器的主要职责是开始、提交或回滚事务。当使用声明式事务管理时,开发者只需要配置相应的事务管理器,而不必亲自编写事务管理的代码
- 代理机制:
Spring 通过代理机制为事务管理提供支持。它使用AOP来在方法调用前后添加额外的逻辑,即切面。在事务管理中,这个额外的逻辑包括开启、提交或回滚事务。
当使用声明式事务管理时,Spring 会动态创建一个代理对象,该代理对象包装了目标对象(拥有业务逻辑的对象)。在方法调用时,代理对象会在执行前后添加事务管理的逻辑
@EnableTransactionManagement:
TransactionManagementConfigurationSelector:
EnableTransactionManagement 会利用 TransactionManagementConfigurationSelector 给容器中会导入两个组件 AutoProxyRegistrar、 ProxyTransactionManagementConfiguration
AutoProxyRegistrar:
AutoProxyRegistrar 给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件,利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用
ProxyTransactionManagementConfiguration:
ProxyTransactionManagementConfiguration 给容器中注册事务增强器
事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
事务拦截器TransactionInterceptor保存了事务属性信息,事务管理器,并且实现了 MethodInterceptor,在目标方法执行的时候执行拦截器链(事务拦截器)
TransactionAspectSupport:
- 先获取事务相关的属性
- 再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger,最终会从容器中按照类型获取一个PlatformTransactionManager
- 执行目标方法,如果异常,获取到事务管理器,利用事务管理回滚操作;如果正常,利用事务管理器,提交事务