在spring事务源码的内部,会有几个比较核心关键的类,虽然这基本上都是源码内部才使用到的类,但是有时候我们要对其做一些改造的时候免不了要去使用到这些类,并且这些类在spring事务内部都是起到关键的作用,对了解spring事务源码的帮助比较大,所以下面我们重点就来理解下这些关键类
事务管理器PlatforomTransactionManager
事务管理器,该接口是spring事务的核心实现接口,它提供了三个方法:
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
- getTransaction
获取一个“逻辑”事务。所谓的“逻辑”事务其实就是spring事务的概念,并不是一个实际上数据库的物理事务
- commit
提交事务,该方法会去实际提交一个实际的数据库事务
- rollback
回滚事务,该方法会去回滚一个实际的数据库事务
对于不同的类型的spring事务,都会有对应的事务管理器实现,比如最常用的spring事务管理器就是DataSourceTransactionManager,还有支撑JPA实现的JpaTransactionManager
事务对象
不同的事务管理器有不同的事务对象实现,比如DataSourceTransactionManager所对应的事务对象就是DataSourceTransactionObject。当通过事务管理器的getTransaction方法去获取一个spring事务的时候,都会创建一个事务对象,而这个事务对象会包含一个实际的数据库连接对象,spring事务对象与实际的数据库事务之间的关系图大致如下:
从上图中可以看到,只要我们创建一个spring事务,对应就都会创建一个spring事务对象,而这个事务对象中封装的就是实际的数据库事务信息(比如其中最核心的connection),只不过根据不同的事务传播级别,创建出来的事务对象中的数据库事务信息有可能是复用线程上下文中已存在的,又或者是一个自己新创建的数据库事务。说到这里,大家应该都知道事务对象在spring事务中一个很重要的类了,那么具体的事务对象是哪个?这里我们主要关注我们最常用的DataSourceTransactionObject
(1)JdbcTransactionObjectSupport
JdbcTransactionObjectSupport是所有事务对象的基类
public abstract class JdbcTransactionObjectSupport implements SavepointManager, SmartTransactionObject {
/**
* 连接对象包装类
*/
@Nullable
private ConnectionHolder connectionHolder;
/**
* 原本数据库的隔离级别
*/
@Nullable
private Integer previousIsolationLevel;
/**
* 当前事务是否只读
*/
private boolean readOnly = false;
private boolean savepointAllowed = false;
......
}
其中它有一个最重要的字段就是ConnectionHolder,ConnectionHolder中就封装数据库连接对象connection
(2)DataSourceTransactionObject
/**
* 该对象是由DataSourceTransactionManager这个事务管理器创建的具体事务对象,
* 每次调用事务方法(无论是否在同一个事务中)都会生成一个DataSourceTransactionObject对象,里面主要是包含了connection连接对象
*/
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
/**
* 当前事务对象所持有的connection对象是否是由当前事务对象所创建的
* (在同一个事务中,如果事务方法a调用事务方法b,事务方法a和事务方法b都会各自创建一个DataSourceTransactionObject对象,
* 不过进来事务方法a的时候就会创建一个新的connection对象,而进来事务方法b的时候会复用事务方法a方法创建的连接对象,也就是两个不同的DataSourceTransactionObject对象使用同一个connection对象)
*/
private boolean newConnectionHolder;
/**
* 是否必须要恢复数据库为自动提交
*/
private boolean mustRestoreAutoCommit;
......
}
DataSourceTransactionObject中最重要的就是newConnectionHolder这个字段,该字段表示的就是当前这个事务对象中包含的connection是否是由它自己创建的,根据上面的流程图我们可以知道,在每一次创建一个spring事务对象的时候,会去看一下线程上下文中是否有事务了,然后再结合spring事务的传播级别去判断是否需要创建一个新的connection,所以如果是复用线程上下文中的事务,则newConnectionHolder就为false,反之,则为true
TransactionStatus
TransactionStatus表示一个spring的事务状态,默认的实现类是DefaultTransactionStatus,当我们每一次去创建一个spring事务的时候,通过上面知道都会创建一个spring事务对象,而除了事务对象之外,还会创建一个TransactionStatus对象,其中TransactionStatus对象会把事务对象包装进去,然后再通过TransactionStatus接口提供的方法去对包装的事务对象进行获取其事务状态信息等
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {
boolean hasSavepoint();
@Override
void flush();
}
TransactionStatus接口继承了TransactionExecution接口以及SavepointManager接口
public interface TransactionExecution {
/**
* 当前事务是否是一个新事务
*/
boolean isNewTransaction();
/**
* 仅设置事务回滚。这会指示事务管理器,事务的唯一可能结果可能是回滚,而不是抛出异常,从而触发回滚
*/
void setRollbackOnly();
/**
* 返回事务是否已标记为仅回滚
*/
boolean isRollbackOnly();
/**
* 事务是否已经完成,无论是已提交还是已回滚都算是已完成
*/
boolean isCompleted();
}
public interface SavepointManager {
Object createSavepoint() throws TransactionException;
void rollbackToSavepoint(Object savepoint) throws TransactionException;
void releaseSavepoint(Object savepoint) throws TransactionException;
}
其中TransactionExecution接口主要就是负责提供对事务的一些处理方法,比如判断事务是否是一个新的事务,判断是否设置了仅回滚状态,判断事务是否已经完成等;而SavepointManager接口见名知意就是与保存点相关的接口,分别提供了创建保存点,回滚保存点,释放保存点这三个方法
TransactionDefinition
TransactionDefinition接口就是用来描述要事务信息的,默认的实现是DefaultTransactionDefinition,每当我们要去创建一个spring逻辑事务的时候,我们首先要知道的是创建出来的事务信息是什么,就好比说你要别人造一个房子,你就需要把这个房子的设计图给到别人,而对应来说TransactionDefinition的作用就去描述一个事务属性,我们根据这个事务属性去创建出对应的spring事务。默认实现的DefaultTransactionDefinition的核心属性如下:
/**
* 事务传播级别
*/
private int propagationBehavior = PROPAGATION_REQUIRED;
/**
* 事务隔离级别
*/
private int isolationLevel = ISOLATION_DEFAULT;
/**
* 事务超时时间
*/
private int timeout = TIMEOUT_DEFAULT;
/**
* 事务是否是只读的
*/
private boolean readOnly = false;
/**
* 事务的名称
*/
@Nullable
private String name;
事务同步器TransactionSynchronization
该类应该是最接近于我们平时开发所要用到的类了,通过该接口我们能够监控spring事务的各个极端,比如在spring事务提交,或者是事务回滚,事务挂起等状态的时候,我们就可以通过该接口来做一些我们想要进行扩展的事情,该接口提供了对spring事务各个阶段的接口方法,对于该组件的详细文章可以到另一篇文章聊聊Spring事务同步器TransactionSynchronization