spring的事物源码解析
文章目录
【注意】最后更新于 October 15, 2018,文中内容可能已过时,请谨慎使用。
spring的事物源码解析
一、注解解析
|
|
TxNamespaceHandler解析XML,AnnotationDrivenBeanDefinitionParser处理相应逻辑;
|
|
1.AopAutoProxyConfigurer.configureAutoProxyCreator
|
|
事物支持核心类BeanFactoryTransactionAttributeSourceAdvisor,TransactionAttributeSourcePointcut,TransactionInterceptor,AnnotationTransactionAttributeSource;核心处理TransactionInterceptor;
- AnnotationTransactionAttributeSource 处理@Transactional注解的属性,map缓存保存RuleBasedTransactionAttribute
- TransactionAttributeSourcePointcut pointcut
- TransactionInterceptor Advice
- BeanFactoryTransactionAttributeSourceAdvisor Advisor
2.TransactionInterceptor invoke
|
|
(1).TransactionAttribute
TransactionDefinition spring事务传播特性和事务的隔离级别定义常量;
事务传播特性:
- PROPAGATION_REQUIERD:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
- PROPAGATION_SUPPORTS:支持当前事务,如果没有当前事务,就以非事务方法执行。
- PROPAGATION_MANDATORY:使用当前事务,如果没有当前事务,就抛出异常。
- PROPAGATION_REQUIRED_NEW:新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER:以非事务方式执行操作,如果当前事务存在则抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
事务的隔离级别:
- read uncommited:是最低的事务隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
- read commited:保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。
- repeatable read:这种事务隔离级别可以防止脏读,不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生(不可重复读)。
- serializable:这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读之外,还避免了幻象读。
脏读、不可重复读、幻象读概念说明:
- 脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。
- 不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。
- 幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)
(2).PlatformTransactionManager
从方法名称就可以看出意思;
①TransactionStatus代表一个事务的具体运行状态,事务管理器通过该接口获取事务的运行期状态信息,也可以通过该接口间接地回滚事务,它相比于在抛出异常时回滚事务的方式更具有可控性。该接口继承于SavepointManager接口,SavepointManager接口基于JDBC3.0保存点的分段事务控制能力提供了嵌套事务的机制。
其中,SavepointManager接口拥有以下的方法:
- Object createSavepoint():创建一个保存点对象,以便在后面可以利用rollbackToSavepoint(Object savepoint)方法使事务回滚到特定的保存点上,也可以通过releaseSavepoint()释放一个已经不用的保存点。
- void rollbackToSavepoint(Object savepoint):将事务回滚到特定保存点上,被回滚的保存点将自动释放。
- void releaseSavepoint(Object savepoint):释放一个保存点,如果事务提交,所有保存点会被自动释放,无须手工清除。 这3个方法在底层资源不支持保存点时,都将抛出NestedTransactionNotSupportedException异常。
②TransactionStatus扩展了SavepointManager并提供了以下方法:
- boolean hasSavepoint():判断当前的事务是否在内部创建了一个保存点,保存点是为了支持Spring的嵌套事务而创建的。
- boolean isNewTransaction():判断当前事务是否是一个新的事务,如果返回false,表示当前事务是一个已经存在的事务,或者当前操作未运行在事务环境中。
- boolean isCompleted():判断当前事务是否已经结束(已经提交或回滚)。
- boolean isRollbackOnly():判断当前事务是否已经被标识为rollback-only。
- void setRollbackOnly():将当前的事务设置为rollback-only,通过该标识通知事务管理器只能将事务回滚,事务管理器将显式调用回滚命令或以抛出异常的方式回滚事务。
(3). DataSourceTransactionManager分析
(a).getTransaction 开始事物
|
|
(b).handleExistingTransaction 处理ThreadLocal获取Connection不为空情况;事务传播情况
|
|
(c).commit(TransactionStatus status) 事物提交
|
|
(d).rollback(TransactionStatus status) 回滚
|
|
(4).createTransactionIfNecessary 事物开启
|
|
(5).completeTransactionAfterThrowing(txInfo, ex);事物异常处理
|
|
二、XML解析
TransactionAttributeSource实现类是NameMatchTransactionAttributeSource;处理事物逻辑 TransactionInterceptor;这里就不做具体分析;