这是我参与更文挑战的第5天,活动详情查看: 更文挑战
我们都知道spring的事务是由Aop实现的,spring会先生成代理对象,然后通过TransactionIntercept调用invoke方法来实现具体的逻辑。这个我们稍后再看
一、相关概念
我们先再复习一下老生常谈的事务的ACID特性
A:atomicity(原子性):操作不能被分割,要么全部成功,要么全部失败。 C:consistency(一致性):事务将数据从一个一致状态转移到另一个一致状态 I: isolation(隔离性):隔离性可以防止多个事务并发执行时由于交叉执行而导致的不一致。 D:durability(持久性):对数据的修改是永久的。
事务的隔离级别:
读未提交(Read Uncommit):可能产生脏读,即读到其他事务未提交的数据 读已提交(Read commit):可能不可重复读的问题,即两次读取结果不一致 可重复读(Repeatable read): 可能发生幻读,数据在update之后可以读到其他已提交事务的数据。(mvcc相关,后续会分享) 可串行化
二、spring事务的相关api
- 事务定义:包含事务的隔离级别和事务的传播行为等信息
- 事务属性:实现了回滚规则的扩展
TransactionAttribute extends TransactionDefinition
boolean rollbackOn(Throwable ex);
- 事务管理器:
public interface PlatformTransactionManager {
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)throws TransactionException;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
- 事务运行时状态:
public interface TransactionStatus extends SavepointManager, Flushable {
boolean isNewTransaction();
boolean hasSavepoint();//回滚到哪个点
void setRollbackOnly();
boolean isRollbackOnly();
@Override
void flush();
boolean isCompleted();
}
- 事务拦截器:TransactionInterceptor
- 事务切面支持:TransactionAspectSupport 内部类TransactionInfo封装了事务的属性。
protected final class TransactionInfo {
@Nullable
private final PlatformTransactionManager transactionManager;
@Nullable
private final TransactionAttribute transactionAttribute;
private final String joinpointIdentification;
@Nullable
private TransactionStatus transactionStatus;
@Nullable
private TransactionInfo oldTransactionInfo;
public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,
@Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {
this.transactionManager = transactionManager;
this.transactionAttribute = transactionAttribute;
this.joinpointIdentification = joinpointIdentification;
}
public PlatformTransactionManager getTransactionManager() {
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
return this.transactionManager;
}
@Nullable
public TransactionAttribute getTransactionAttribute() {
return this.transactionAttribute;
}
/**
* Return a String representation of this joinpoint (usually a Method call)
* for use in logging.
*/
public String getJoinpointIdentification() {
return this.joinpointIdentification;
}
public void newTransactionStatus(@Nullable TransactionStatus status) {
this.transactionStatus = status;
}
@Nullable
public TransactionStatus getTransactionStatus() {
return this.transactionStatus;
}
/**
* Return whether a transaction was created by this aspect,
* or whether we just have a placeholder to keep ThreadLocal stack integrity.
*/
public boolean hasTransaction() {
return (this.transactionStatus != null);
}
private void bindToThread() {
// Expose current TransactionStatus, preserving any existing TransactionStatus
// for restoration after this transaction is complete.
this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);
}
private void restoreThreadLocalStatus() {
// Use stack to restore old transaction TransactionInfo.
// Will be null if none was set.
transactionInfoHolder.set(this.oldTransactionInfo);
}
@Override
public String toString() {
return (this.transactionAttribute != null ? this.transactionAttribute.toString() : "No transaction");
}
}
我们前文提到的事务拦截器TransactionInterceptor在invoke方法中,通过调用父类TransactionAspectSupport的invokeWithinTransaction方法进行事务处理,该方法支持声明式事务和编程式事务。
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,final InvocationCallback invocation) throws Throwable {
//查询目标方法事务属性、确定事务管理器、构造连接点标识(用于确认事务名称)
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 事务获取
TransactionInfotxInfo=createTransactionIfNecessary(tm,txAttr,joinpointIdentification);
Object retVal;
try {
// 通过回调执行目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
//目标方法执行抛出异常,根据异常类型执行事务提交或者回滚操作
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清理当前线程事务信息
cleanupTransactionInfo(txInfo);
}
//目标方法执行成功,提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
以上,感谢阅读。