首页 > 编程学习 > 【spring事务源码学习】--- spring事务三大接口简介

文章目录

  • 1 前言
  • 2 TransactionDefinition接口
  • 3 PlatformTransactionManager接口
  • 4 TransactionStatus接口


1 前言

spring为管理事务定义了三个接口,分别为

  • TransactionDefinition — 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
  • TransactionStatus — 事务的运行状态
  • PlatformTransactionManager — (平台)事务管理器

它们之间的关系大致为:PlatformTransactionManager根据TransactionDefinition 进行事务管理,管理过程中事务存在多种状态,每个状态信息通过 TransactionStatus 表示。本文将比较详细的介绍一下这三个接口。


2 TransactionDefinition接口

TransactionDefinition接口定义了5个方法以及一些表示事务属性的常量比如事务的隔离级别、传播行为等。其具体源码如下:

public interface TransactionDefinition {//-------------------------------------事务的七大传播行为---------------------------------------------/***如果当前没有事务,就新建一个事务,如果已经存在一个事务中,则加入到这个事务中*/int PROPAGATION_REQUIRED = 0;/***如果当前有事务,支持当前事务;如果当前没有事务,就以非事务方式执行*/int PROPAGATION_SUPPORTS = 1;/***使用当前事务,如果当前没有事务,就抛出异常*/int PROPAGATION_MANDATORY = 2;/***新建事务,如果当前存在事务,把当前事务挂起*/int PROPAGATION_REQUIRES_NEW = 3;/***以非事务方式执行操作,如果当前存在事务,就把当前事务挂起*/int PROPAGATION_NOT_SUPPORTED = 4;/***以非事务方式执行,如果当前存在事务,则抛出异常*/int PROPAGATION_NEVER = 5;/***如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作*/int PROPAGATION_NESTED = 6;//-------------------------------------事务的四大隔离级别---------------------------------------/***使用数据库默认的隔离级别,比如MySQL默认采用REPEATABLE_READ,Oracle默认采用READ_COMMITTED*/int ISOLATION_DEFAULT = -1;/***最低的隔离级别,允许读取尚未提交的数据变更,可能导致脏读、不可重复读和幻读*/int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;/***允许读取开发事务已提交的数据,可以阻止脏读,但是不可重复读和幻读有可能发生*/int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;/***对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改,可以防止脏读和不可重复读,但是幻读可能发生*/int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;/***最高隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,该级别可以防止脏读、不可重复度和幻读,但是这将严重影响程序的性能,因此通常情况下根本不会用到该级别*/int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;/*** Use the default timeout of the underlying transaction system,* or none if timeouts are not supported.*/int TIMEOUT_DEFAULT = -1;//-------------------------------------一些方法---------------------------------------/***获取事务的传播行为*/int getPropagationBehavior();/***获取事务的隔离级别*/int getIsolationLevel();/***获取事务的超时时间*/int getTimeout();/***返回当前事务是否为只读事务*/boolean isReadOnly();/***获取当前事务的名称*/@NullableString getName();
}

3 PlatformTransactionManager接口

PlatformTransactionManager为事务管理器的顶级接口,其源码如下:

public interface PlatformTransactionManager {/***获取事务状态*/TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws TransactionException;/***进行事务提交*/void commit(TransactionStatus status) throws TransactionException;/***进行事务回滚*/void rollback(TransactionStatus status) throws TransactionException;
}

提到事务管理器接口就不得不提设计模式中的模版模式。相信大家肯定都知道对于JDBC来说进行事务的开启、关闭与回滚其实都是对Connection对象的操作,而Hibernate则使用的是Session,两者的事务管理器肯定不可能是一个;同时不同的持久层框架,可能针对事务的管理也不尽相同。但是尽管如此,对于事务的管理,肯定还是可以抽象出很多相同的方法或属性,于是spring定义了一个顶级接口PlatformTransactionManager用来规定事务的基本操作,即获取事务状态、进行事务提交和进行事务回滚。同时还提供了一个抽象类AbstractPlatformTransactionManager用来定义一些关于事务管理的公共方法和属性。并且针对JTA和JDBC提供了相应事务管理器的具体实现 — JtaTransactionManager和DataSourceTransactionManager。继承和实现关系如下:
在这里插入图片描述


当然如果您的项目使用的是hibernate或spring-data-jpa作为持久层框架的话,spring也为此提供了事务管理器的具体实现,我们可以在pom.xml中导入spring-data-jpa(spring-data-jpa底层也用到了hibernate,因此导入spring-data-jpa的包可以同时获得jpa的事务管理器和hibernate的事务管理器)的包来验证一下:

  • jar包
 <!--jpa--><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-jpa</artifactId><version>2.2.0.RELEASE</version></dependency>
  • 事务管理器的继承和实现关系:

在这里插入图片描述
通过上图可以看到 spring 确实是利用模版模式为各种持久层框架提供其适用的事务管理器。
如果仔细看一下这些事务管理器相关的接口、抽象类和实现类的作者,你会发现竟然都是一个人:

@author Juergen Hoeller

牛!!!


4 TransactionStatus接口

TransactionStatus接口用来记录事务的状态,该接口定义了一组方法,用来获取或判断事务的状态信息。

注意:PlatformTransactionManager接口中getTransaction(…)方法可能是获取一个在当前调用堆栈中已经存在的事务>状态对象 — TransactionStatus ,也可能能是新建一个事务,并获取到该事务的事务状态对象。

TransactionStatus接口源码如下:

public interface TransactionStatus extends SavepointManager, Flushable {/***当前事务是否为新事物*/boolean isNewTransaction();/***是否有保存点 --- 传播行为里NESTED就是用savepoint来实现的。*/boolean hasSavepoint();/***设置为只回滚 --- 传播行为是REQUIRED,内层子级报异常,父级肯定回滚就用到了rollback-only*/void setRollbackOnly();/***是否为只回滚*/boolean isRollbackOnly();/*** Flush the underlying session to the datastore, if applicable:* for example, all affected Hibernate/JPA sessions.* <p>This is effectively just a hint and may be a no-op if the underlying* transaction manager does not have a flush concept. A flush signal may* get applied to the primary resource or to transaction synchronizations,* depending on the underlying resource.*/@Overridevoid flush();/***判断当前事务是否已经完成*/boolean isCompleted();
}

本文链接:https://www.ngui.cc/el/1113708.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000