# Spring 事务
## Spring管理事务的方式
- 编程式事务
- 声明式事务(通过XML/注解配置)
## Spring声明式事务的内部实现方式


> 可以看到PlatformTransactionManager这个接口主要定义了3个方法
getTransaction获取事务,commit提交,rollback回滚

AbstractPlatformTransactionManager抽象类实现了Spring事务的标准流程,其子类DataSourceTransactionManager是我们使用较多的JDBC单数据源事务管理器,而JtaTransactionManager是JTA(Java Transaction API)规范的实现类,另外两个则分别是JavaEE容器WebLogic和WebSphere的JTA事务管理器的具体实现。
## TransactionInterceptor#invoke()拦截入口

当执行`decreaseStock()`时我们首先关注
`org.springframework.transaction.interceptor#TransactionInterceptor//可以认为`下的`invoke`方法,**这里是拦截入口**,在这里可以看到真正执行事务配置的还是TransactionInterceptor父类TransactionAspectSupport的`invokeWithinTransaction方法`,参数1表示被调用的方法,在这里**就是**我们被`@Transactional`修饰的`createOrder`方法;参数2表明是哪一个target class调用了该方法,在这里是`service.impl.OrderServiceImpl`
## TransactionAspectSupport类
```java
// 通过BeanFactoryAware获取到BeanFactory
// InitializingBean的afterPropertiesSet是对Bean做一些验证(经常会借助它这么来校验Bean~~~)
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
// 注意此方法是个静态方法 并且是protected的 说明只有子类能够调用,外部并不可以~~~
@Nullable
protected static TransactionInfo currentTransactionInfo() throws NoTransactionException {
return transactionInfoHolder.get();
}
// 外部调用此Static方法,可获取到当前事务的状态
public static TransactionStatus currentTransactionStatus() throws NoTransactionException {
TransactionInfo info = currentTransactionInfo();
if (info == null || info.transactionStatus == null) {
throw new NoTransactionException("No transaction aspect-managed TransactionStatus in scope");
}
return info.transactionStatus;
}
···
// 接下来就只剩我们最为核心的处理事务的模版方法了:
//protected修饰,不允许其他包和无关类调用
@Nullable
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);
/*响应式编程的事务支持 我们这里
不深入探讨(加入学习计划,指响应式编程~*/
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
···
}
// 转换为标准的PlatformTransactionManager
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 拿到目标方法唯一标识(类.方法,如service.impl.OrderServiceImpl#createOrder)
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 如果txAttr为空 或者tm不属于CallbackPreferringPlatformTransactionManager(需要通过回调函数实现事务),执行目标增强
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 创建事务对象,其中保存了事务状态对象(无论是否真的有创建)
// TransactionInfo是一个事务对象,对象中包含事务的所有属性,包括PlatformTransactionManager、TransactionAttribute、TransactionStatus
// ⚠️事务的管理都是通过TransactionInfo对象来完成,它封装了事务对象和事务处理的状态信息
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
//回调方法执行,执行目标方法(原有的业务逻辑)
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 出现异常了,进行回滚(注意:并不是所有异常都会rollback的)
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清除信息
cleanupTransactionInfo(txInfo);
}
// 目标方法完全执行完成后,提交事务~~~
commitTransactionAfterReturning(txInfo);
return retVal;
}
//编程式事务处理(CallbackPreferringPlatformTransactionManager) 会走这里
//原理类似 这里跳过
else {
···
}
// 确定当前事务的事务管理器
@Nullable
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
// 如果这两个都没配置,所以肯定是手动设置了PlatformTransactionManager的,那就直接返回即可
if (txAttr == null || this.beanFactory == null) {
return getTransactionManager();
}
// qualifier 指定特定的事务管理器
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
// 若没有指定qualifier 那再看看是否指定了 transactionManagerBeanName
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
}
// 若都没指定,那就不管了。直接根据类型去容器里找 getBean(Class)
else {
TransactionManager defaultTransactionManager = getTransactionManager();
if (defaultTransactionManager == null) {
defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
// 此处:若容器内有两个PlatformTransactionManager ,那就铁定会报错啦~~~
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
// 如果事务管理器默认缓存(存储默认事务管理器的专用key值DEFAULT_TRANSACTION_MANAGER_KEY)中为空就加入缓存 this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
}
```
---


Spring 从源码看事务——TransactionInterceptor事务拦截器&AOP