文章目录
Spring事物源码分析-TransactionStatus
一、TransactionStatus接口
-
TransactionStatus表示一个事物的状态。接口提供了控制事务执行和查询事务状态的方法。比如当前调用栈中之前已经存在了一个事物,那么就是通过该接口来判断的,TransactionStatus接口可以让事务管理器控制事务的执行,比如检查事务是否为一个新事务,或者是否只读,TransactionStatus还可以初始化回滚操作。
-
接口继承了SavepointManager接口,因此封装了事物中回滚点的相关操作
-
SavepointManager接口:
public interface SavepointManager {
//1.创建回滚点
Object createSavepoint() throws TransactionException;
//2.回滚到回滚点
void rollbackToSavepoint(Object savepoint) throws TransactionException;
//3.释放回滚点
void releaseSavepoint(Object savepoint) throws TransactionException;
}
- TransactionStatus接口:
public interface TransactionStatus extends SavepointManager, Flushable {
//是否是一个新的事物
boolean isNewTransaction();
//判断是否有回滚点
boolean hasSavepoint();
//将一个事务标识为不可提交的。在调用完setRollbackOnly()后只能被回滚
//在大多数情况下,事务管理器会检测到这一点,在它发现事务要提交时会立刻结束事务。
//调用完setRollbackOnly()后,数数据库可以继续执行select,但不允许执行update语句,因为事务只可以进行读取操作,任何修改都不会被提交。
void setRollbackOnly();
boolean isRollbackOnly();
@Override
void flush();
//判断事物是否已经完成
boolean isCompleted();
}
二、DefaultTransactionStatus(实现类)
- DefaultTransactionStatus是 TransactionStatus的一个实现类
public class DefaultTransactionStatus extends AbstractTransactionStatus {
//1.相关属性
private final Object transaction;
private final boolean newTransaction;
private final boolean newSynchronization;
private final boolean readOnly;
private final boolean debug;
private final Object suspendedResources;
//2.构造方法
public DefaultTransactionStatus(
@Nullable Object transaction, boolean newTransaction, boolean newSynchronization,
boolean readOnly, boolean debug, @Nullable Object suspendedResources) {
this.transaction = transaction;
this.newTransaction = newTransaction;
this.newSynchronization = newSynchronization;
this.readOnly = readOnly;
this.debug = debug;
this.suspendedResources = suspendedResources;
}
//3.获取事物,在jdbc中事务是通过Connection来实现,Hibernate是通过自己定义的Transaction来实现的,各家的事务都不同,
//因此Spring只能以Object transaction的形式来表示各家的事务,事务的回滚和提交等操作都会最终委托给上述Object transaction来完成
public Object getTransaction() {
Assert.state(this.transaction != null, "No transaction active");
return this.transaction;
}
public boolean hasTransaction() {
return (this.transaction != null);
}
@Override
public boolean isNewTransaction() {
return (hasTransaction() && this.newTransaction);
}
public boolean isNewSynchronization() {
return this.newSynchronization;
}
public boolean isReadOnly() {
return this.readOnly;
}
public boolean isDebug() {
return this.debug;
}
public Object getSuspendedResources() {
return this.suspendedResources;
}
public boolean isGlobalRollbackOnly() {
return ((this.transaction instanceof SmartTransactionObject) &&
((SmartTransactionObject) this.transaction).isRollbackOnly());
}
public void flush() {
if (this.transaction instanceof SmartTransactionObject) {
((SmartTransactionObject) this.transaction).flush();
}
}
protected SavepointManager getSavepointManager() {
Object transaction = this.transaction;
if (!(transaction instanceof SavepointManager)) {
throw new NestedTransactionNotSupportedException(
"Transaction object [" + this.transaction + "] does not support savepoints");
}
return (SavepointManager) transaction;
}
public boolean isTransactionSavepointManager() {
return (this.transaction instanceof SavepointManager);
}
}
- Object transaction的可能取值:DataSourceTransactionObject、HibernateTransactionObject或者JpaTransactionObject
DataSourceTransactionObject: 使用dataSource来获取连接,要想实现事务功能,必然需要使用Connection,所以
肯定有一个Connection来执行事务的操作。DataSourceTransactionObject中有一个ConnectionHolder,它封装了一
个Connection,由此来实现底层的事物操作。
HibernateTransactionObject: 我们hibenrate时,要想实现事务功能需要通过hibernate自己定义的Transaction来实
现。HibernateTransactionObject中含有一个SessionHolder,和上面的ConnectionHolder一样,它封装了一个Session,
有了Session,我们就可以通过Session来产生一个Hibernate的Transaction,从而实现事务操作。
JpaTransactionObject: JPA相关
三、TransactionStatus和PlatformTransactionManager
- 事物管理器PlatformTransactionManager可以获取TransactionStatus,这个在管理器的顶层接口中有定义
public interface PlatformTransactionManager {
/**
* 或者当前活跃事物的事物状态,或者创建一个新的
* Return a currently active transaction or create a new one, according to
* the specified propagation behavior.
*/
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
//其他方法...
}
- 我们看看PlatformTransactionManager子类AbstractPlatformTransactionManager对该方法的实现,这个方法其实不陌生,在《Spring事物03-源码分析TransactionInterceptor》中我们分析的,拦截器的invoke方法最后就是调用这个方法来开启事物,里面会处理传播属性的各种情况。这里只看获取TransactionStatus,实际上获取的是DefaultTransactionStatus实例,这里面首先会获取Object transaction ,然后构造DefaultTransactionStatus对象返回。
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction();
//省略...
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
//省略...
}
- 这里面获取Object transaction之后,是从线程绑定的获取的,可能当前线程已经存在事务
四、TransactionStatus和事物操作
-
getTransaction获取TransactionStatus的时候,可能会根据事物传播做不同的处理,因此我们来看看不同的情况返回的TransactionStatus有什么不一样,这些可以在getTransaction里面的handleExistingTransaction调用中看到。
-
存在事物时,有时候会抛出异常,有时候会返回一个TransactionStatus,我们关注创建新事物的情况,如果不存在事物并且为PROPAGATION_REQUIRED,就需要创建新事物
private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled) throws TransactionException {
//省略......
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
//需要创建一个新的事物,构造一个新的DefaultTransactionStatus,传进去必要的属性
//比如TransactionDefinition事物属性,transaction事物对象,以及其他事物状态属性
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
//省略......
//后面也有通过构造方法构造DefaultTransactionStatus返回的情况,就不写了,省略......
}
五、小结
- TransactionStatus用于保存当前事物状态,比如是否只能回滚、是否包含回滚点、是否只读,其实现类内部包含事物操作对象transaction
- 事物操作对象transaction包含不同的实现,比如JDBC的DataSourceTransactionObject、Hibernate的HibernateTransactionObject等。