事务处理的实现
Spring
在对事务进行统一处理其实底层还是使用到了aop
,TransactionProxyFactoryBean
将对事务的处理事件使用aop
做增强和织入。对数据源的事务处理(提交、回滚)的实现是通过事务管理器TransactionManager
来进行支持的。通过TransactionAspectSupport
来赋予TransactionManager
的事务处理可以通过aop
进行操作。
事务处理拦截器的配置
事务处理拦截器是对target
的方法进行拦截,然后调用TransactionManager
对方法的事务进行管理。
事务处理拦截器是在TransactionProxyFactoryBean
的父类AbstractSingletonProxyFactoryBean
中进行配置的。在bean
的生命周期中,在处理init-method
的方法中,先调用后置处理器的before
,然后如果是InitializingBean
类型的bean
还会执行afterPropertiesSet
方法,然后才会依次执行init-method
和后置处理器的after
方法。
afterPropertiesSet方法
// AbstractSingletonProxyFactoryBean#afterPropertiesSet
public void afterPropertiesSet() {
// <1> 对target的;类型进行检查,必须是一个bean reference
if (this.target == null) {
throw new IllegalArgumentException("Property 'target' is required");
}
if (this.target instanceof String) {
throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
}
if (this.proxyClassLoader == null) {
this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
}
// 创建一个ProxyFactory,和aop中的ProxyFactoryBean功能很相近,
// 能够操作拦截器和创建代理对象
ProxyFactory proxyFactory = new ProxyFactory();
// <2> 将拦截器包装成为advisor,通过aop知道ProxyFactory可以管理advisor,进而操作通知器链等
// 首先是preInterceptors 然后加入TransactionInterceptor的advisor 最后postInterceptors
if (this.preInterceptors != null) {
for (Object interceptor : this.preInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}
// Add the main interceptor (typically an Advisor).
// <3> 这是对TransactionInterceptor创建对应的advisor
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
if (this.postInterceptors != null) {
for (Object interceptor : this.postInterceptors) {
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
}
}
// 对proxyFactory进行一些设置,在使用proxyFactory创建代理对象的时候需要
proxyFactory.copyFrom(this);
TargetSource targetSource = createTargetSource(this.target);
proxyFactory.setTargetSource(targetSource);
if (this.proxyInterfaces != null) {
proxyFactory.setInterfaces(this.proxyInterfaces);
}
else if (!isProxyTargetClass()) {
// Rely on AOP infrastructure to tell us what interfaces to proxy.
Class<?> targetClass = targetSource.getTargetClass();
if (targetClass != null) {
proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
}
postProcessProxyFactory(proxyFactory);
// <4> 创建代理对象,过程和aop中的一样(拦截器链在这个方法中已经构建好了)
this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
}
<3>
中的wrap
和aop
中的方法是一样的。重点在于createMainInterceptor
方法做了什么。Interceptor
需要有Advice
和Pointcut
。
如果已经存在pointcut
就是使用DefaultPointcutAdvisor
,否则就创建TransactionAttributeSourceAdvisor
。
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
protected Object createMainInterceptor() {
// 做一些检查
this.transactionInterceptor.afterPropertiesSet();
if (this.pointcut != null) {
return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
}
else {
// Rely on default pointcut.
return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
}
}
事务处理配置的读入
TransactionAttributeSourceAdvisor类
这是在事务处理中比较常用的通知器。通知器需要有Advice
和Pointcut
,它是如何配置的。Advice
其实就是TransactionInterceptor
。Pointcut
其实就是TransactionAttributeSourcePointcut
,可以从对事务的配置属性中读取信息。
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return (transactionInterceptor != null ? transactionInterceptor.getTransactionAttributeSource() : null);
}
};
TransactionAttributeSourcePointcut类
在这个类中就实现了对拦截方法的检查,是否能够拦截该事务。
使用TransactionAttributeSource
,根据方法名判断是否有匹配的TransactionAttribute
如果有那么就可以拦截。而TransactionAttributeSource
通过TransactionInterceptor
获得。TransactionAttributeSource
属性是TransactionInterceptor
在注入依赖的时候配置好的。
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
// TransactionAspectSupport#setTransactionAttributes
public void setTransactionAttributes(Properties transactionAttributes) {
NameMatchTransactionAttributeSource tas = new NameMatchTransactionAttributeSource();
tas.setProperties(transactionAttributes);
this.transactionAttributeSource = tas;
}
// NameMatchTransactionAttributeSource#getTransactionAttribute
/** Keys are method names; values are TransactionAttributes. */
private Map<String, TransactionAttribute> nameMap = new HashMap<>();
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (!ClassUtils.isUserLevelMethod(method)) {
return null;
}
// Look for direct name match.
String methodName = method.getName();
TransactionAttribute attr = this.nameMap.get(methodName);
if (attr == null) {
// Look for most specific name match.
String bestNameMatch = null;
for (String mappedName : this.nameMap.keySet()) {
if (isMatch(methodName, mappedName) &&
(bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
attr = this.nameMap.get(mappedName);
bestNameMatch = mappedName;
}
}
}
return attr;
}
事务处理器拦截器的作用
TransactionProxyFactoryBean
的getObject
方法获取代理对象。
// AbstractSingletonProxyFactoryBean#getObject
public Object getObject() {
if (this.proxy == null) {
throw new FactoryBeanNotInitializedException();
}
return this.proxy;
}
proxy
就是在执行afterPropertiesSet
方法时进行设置的。和aop
一样是通过DefaultAopProxyFactory
的createAopProxy
方法创建。所以在执行通知器链的时候对target
的代理实现原理也是一样的。具体的不同就是多了专门用来处理事务的拦截器TransactionInterceptor
。
在遍历MethodInterceptor
的时候会执行invoke
方法。那么TransactionInterceptor
的invoke
就是对target
的方法能够进行事务处理的地方,所以在invoke
方法中会使用到TransactionManager
。
invoke方法
// TransactionInterceptor#invoke
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);
// <1> Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
<1>
最后是使用lambda
表达式创建了一个InvocationCallback
对象,当调用InvocationCallback#proceedWithInvocation
的时候会调用ReflectiveMethodInvocation#proceed
。
invokeWithinTransaction方法
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
// 得到事务属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 得到事务管理器
final TransactionManager tm = determineTransactionManager(txAttr);
// <1> 有关于reactive响应式的事务管理器
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method +
". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapt