相关阅读
- Spring Boot源码简析 @EnableTransactionManagement
- Spring AOP基础组件 AopProxyFactory
- Spring AOP基础组件 Advice
- Spring AOP基础组件 Advisor
简介
本文主要介绍Spring Boot事务的配置解析和执行实现;
Demo
public class DemoService {
@Transactional
public void save() {
// save
throw new RuntimeException();
}
}
如果save
方法在执行过程中发生异常,且满足回滚要求(默认情况下RuntimeException
满足事务回滚要求,可见DefaultTransactionAttribute.rollbackOn
实现),那么发生异常前的数据库操作都会被回滚;
配置解析
Spring Boot事务核心功能主要由以下类实现:
InfrastructureAdvisorAutoProxyCreator
,为带有事务属性的方法创建代理;BeanFactoryTransactionAttributeSourceAdvisor
,事务管理核心Advisor
;AnnotationTransactionAttributeSource
,解析方法的事务属性;TransactionInterceptor
,执行带有事务属性的方法;
Spring Boot支持两种配置方式:XML配置和注解配置,两种方式都会注册以上类型的Bean;
以上类型的Bean的功能详见注解配置;
XML配置
配置文件
开始事务配置如下:
<tx:annotation-driven transaction-manager="transactionManager" />
解析
annotation-driven
标签的解析实现是在TxNamespaceHandler
中配置,代码如下:
@Override
public void init() {
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
可知,annotation-driven
标签的解析由AnnotationDrivenBeanDefinitionParser
完成,其parse
方法用于解析该标签,实现如下:
public BeanDefinition parse(Element element, ParserContext parserContext) {
this.registerTransactionalEventListenerFactory(parserContext);
// annotation-driven 的mode属性支持aspectj和proxy
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// 是aspectj模式
this.registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent("javax.transaction.Transactional", this.getClass().getClassLoader())) {
this.registerJtaTransactionAspect(element, parserContext);
}
} else {
// 否则就是proxy模式
AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
private void registerTransactionAspect(Element element, ParserContext parserContext) {
String txAspectBeanName = "org.springframework.transaction.config.internalTransactionAspect";
String txAspectClassName = "org.springframework.transaction.aspectj.AnnotationTransactionAspect";
// 注册org.springframework.transaction.config.internalTransactionAspect
if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) {
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(txAspectClassName);
def.setFactoryMethodName("aspectOf");
registerTransactionManager(element, def);
parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName));
}
}
private void registerJtaTransactionAspect(Element element, ParserContext parserContext) {
String txAspectBeanName = "org.springframework.transaction.config.internalJtaTransactionAspect";
String txAspectClassName = "org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect";
// 注册org.springframework.transaction.config.internalJtaTransactionAspect
if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) {
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(txAspectClassName);
def.setFactoryMethodName("aspectOf");
registerTransactionManager(element, def);
parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName));
}
}
private void registerAsyncExecutionAspect(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ASYNC_EXECUTION_ASPECT_CLASS_NAME);
// 设置aspectOf属性
builder.setFactoryMethod("aspectOf");
// 设置executor属性
String executor = element.getAttribute("executor");
if (StringUtils.hasText(executor)) {
builder.addPropertyReference("executor", executor);
}
// 设置exception-handler属性
String exceptionHandler = element.getAttribute("exception-handler");
if (StringUtils.hasText(exceptionHandler)) {
builder.addPropertyReference("exceptionHandler", exceptionHandler);
}
// 注册org.springframework.scheduling.config.internalAsyncExecutionAspect
parserContext.registerBeanComponent(new BeanComponentDefinition(builder.getBeanDefinition(),
TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME));
}
}
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 注册InfrastructureAdvisorAutoProxyCreator如果需要的话
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
// 是否已注册org.springframework.transaction.config.internalTransactionAdvisor
// 若已注册,则无需再注册
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// 准备AnnotationTransactionAttributeSource
RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(2);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// 准备TransactionInterceptor
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(2);
AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
// 注入AnnotationTransactionAttributeSource
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// 准备BeanFactoryTransactionAttributeSourceAdvisor
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(2);
// 注入AnnotationTransactionAttributeSource
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 注入TransactionInterceptor
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
// 注册BeanFactoryTransactionAttributeSourceAdvisor BeanDefinition
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
// 构建CompositeComponentDefinition完成以上Bean注册
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
注解配置
注解的配置方式,主要是引入@EnableTransactionManagement
注解,该注解的详细介绍可见:
Spring Boot源码简析 @EnableTransactionManagement
执行
TransactionInterceptor
支撑了整个事务功能的架构,该类继承自TransactionAspectSupport
,核心代码如下:
// TransactionInterceptor.java
public Object invoke(MethodInvocation invocation) throws Throwable {
// 获取当前Bean的类型
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
@Override
@Nullable
public Object proceedWithInvocation() throws Throwable {
// 执行原始方法
return invocation.proceed();
}
@Override
public Object getTarget() {
return invocation.getThis();
}
@Override
public Object[] getArguments() {
return invocation.getArguments();
}
});
}
// TransactionAspectSupport.java
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 TransactionManager tm = determineTransactionManager(txAttr);
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
boolean hasSuspendingFlowReturnType = isSuspendingFunction &&
COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName());
if (isSuspendingFunction && !(invocation instanceof CoroutinesInvocationCallback)) {
throw new IllegalStateException("Coroutines invocation not supported: " + method);
}
CoroutinesInvocationCallback corInv = (isSuspendingFunction ? (CoroutinesInvocationCallback) invocation : null);
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
Class<?> reactiveType =
(isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType());
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
InvocationCallback callback = invocation;
if (corInv != null) {
callback = () -> CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
}
Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager) tm);
if (corInv != null) {
Publisher<?> pr = (Publisher<?>) result;
return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow(pr) :
KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation()));
}
return result;
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 获取方法的唯一标识符
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 如果不存在事务属性,或者事务管理器不是CallbackPreferringPlatformTransactionManager类型
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 标准的事务生命周期管理:getTransaction/commit/rollback
// 创建事务信息,根据事务属性决定是否创建事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 执行原始方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 发生异常,则根据具体异常完成事务(若满足回滚条件才进行回滚)
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 清除事务信息
cleanupTransactionInfo(txInfo);
}
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
// 原始方法成功执行完,则可以提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
Object result;
final ThrowableHolder throwableHolder = new ThrowableHolder();
try {
// 交给事务管理器执行
result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
// 准备事务信息
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
// 执行原始方法
Object retVal = invocation.proceedWithInvocation();
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
// 判断基于当前异常是否回滚
if (txAttr.rollbackOn(ex)) {
// RuntimeException可以触发事务回滚(DefaultTransactionAttribute实现)
// Spring框架认为Checked的异常属于业务的,coder需要处理
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// 无需回滚,但因为发生异常,需要返回null
throwableHolder.throwable = ex;
return null;
}
}
finally {
// 清除事务信息
cleanupTransactionInfo(txInfo);
}
});
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
if (throwableHolder.throwable != null) {
// 存在异常则需要抛出
throw throwableHolder.throwable;
}
return result;
}
}
获取事务属性
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
事务属性配置
TransactionInterceptor
是由ProxyTransactionManagementConfiguration
配置器构建,在构建时注入AnnotationTransactionAttributeSource
,代码如下:
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
// 默认构建AnnotationTransactionAttributeSource
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
// 注入的TransactionAttributeSource默认为AnnotationTransactionAttributeSource
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
事务属性解析
所以tas
为AnnotationTransactionAttributeSource
,其getTransactionAttribute(method, targetClass)
实现继承自父类AbstractFallbackTransactionAttributeSource
,代码如下:
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
// 已解析的结果会被缓存,故先尝试从缓存中获取,获取不到再进行解析
// 缓存的Key就是方法的唯一标识符
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
// 缓存中存在,则直接使用缓存值
// 缓存时对NULL值做特殊处理,此处需要转换为NULL值
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
// 缓存中还不存在,那么就需要进行解析
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// 缓存解析结果,方便下次使用
if (txAttr == null) {
// NULL值特殊处理,便于存储
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
}
else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
// 针对DefaultTransactionAttribute的处理
DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
dta.setDescriptor(methodIdentification);
dta.resolveAttributeStrings(this.embeddedValueResolver);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 是否只允许public方法
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 找到该targetClass(如果存在的话)实现该method的Method
// 如果method就是在targetClass中定义,或者targetClass没有重写method,那么specificMethod和method一致
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 优先使用实现类重写的方法上的事务属性,如果存在的话
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 其次使用实现类上的事务属性,如果存在的话
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
// 如果方法定义和实现不一致,那么尝试获取定义时的事务属性
if (specificMethod != method) {
// 再次使用方法定义时方法上的事务属性,如果存在的话
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// 最后使用方法定义时所在的类上的事务属性,如果存在的话
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);
protected abstract TransactionAttribute findTransactionAttribute(Method method);
父类AbstractFallbackTransactionAttributeSource
实现了解析事务属性的算法模板,将算法细节findTransactionAttribute(Class<?> clazz)
和findTransactionAttribute(Method method)
留给子类去实现,AnnotationTransactionAttributeSource
的实现如下:
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
// 遍历内部的事务注解解析器
for (TransactionAnnotationParser parser : this.annotationParsers) {
// 使用事务注解解析器解析方法或者类上的事务注解得到事务属性
TransactionAttribute attr = parser.parseTransactionAnnotation(element);
if (attr != null) {
// 若解析得到事务属性,则直接返回使用,不再进行下一个
return attr;
}
}
return null;
}
用户可以指定TransactionAnnotationParser
,默认值是在构建时设置的,代码如下:
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
最常用的就是SpringTransactionAnnotationParser
,其parseTransactionAnnotation
方法实现如下:
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// 获取AnnotatedElement上的@Transactional注解
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
// 存在Transactional注解,则转换为TransactionAttribute
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
/**
* 将@Transactional的属性转换为TransactionAttribute
*/
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = attributes.getEnum("propagation");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
String timeoutString = attributes.getString("timeoutString");
Assert.isTrue(!StringUtils.hasText(timeoutString) || rbta.getTimeout() < 0,
"Specify 'timeout' or 'timeoutString', not both");
rbta.setTimeoutString(timeoutString);
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
rbta.setLabels(Arrays.asList(attributes.getStringArray("label")));
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
创建事务
执行原始方法前,需要先创建事务(如果需要的话),代码如下:
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// 如果事务未指定name,那么使用方法的唯一标识符作为事务名称
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 根据事务属性获取事务
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
// 根据事务属性和事务状态准备事务
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
PlatformTransactionManager tm
会由determineTransactionManager
确认,支持事务属性指定事务管理器,实现代码如下:
protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
// 如果不存在事务属性,那么不需要确保找到事务管理器
// 如果BeanFactory不存在,那么只能选择默认事务管理器
if (txAttr == null || this.beanFactory == null) {
// 直接返回默认事务管理器,此时默认事务管理器可能未设置
// 是在ProxyTransactionManagementConfiguration构建TransactionInterceptor时设置
return getTransactionManager();
}
// 存在事务属性,则获取其指定的事务管理器若存在的话
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
// 根据指定的BeanName从BeanFactory找到对应的事务管理器
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
// 如果设置了默认的事务管理器BeanName,则在BeanFactory中找到对应的事务管理器
return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
}
else {
// 使用默认的事务管理器
TransactionManager defaultTransactionManager = getTransactionManager();
if (defaultTransactionManager == null) {
// 默认的事务管理器不存在,则尝试获取缓存中的事务管理器(如果之前获取到,那么就会被缓存,此时可以直接从缓存获取)
defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
// 缓存中还不存在事务管理器,就从BeanFactory中找到任意一个事务管理器
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
// 缓存找到的事务管理器,方便下次直接使用
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
使用数据库时,我们使用的事务管理器一般都是DataSourceTransactionManager
,其getTransaction(@Nullable TransactionDefinition definition)
方法实现继承自父类AbstractPlatformTransactionManager
,代码如下:
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// 使用默认值如果不存在事务属性的话
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
// 获取当前事务
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
// 当前已经存在事务的处理
if (isExistingTransaction(transaction)) {
return handleExistingTransaction(def, transaction, debugEnabled);
}
// 事务超时校验
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
// 当前不存在事务
// 事务传播属性设置为PROPAGATION_MANDATORY
// 当前不存在事务就需要抛出异常
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
// 事务传播属性设置为PROPAGATION_REQUIRED或者PROPAGATION_REQUIRES_NEW或者PROPAGATION_NESTED
// 这些类型需要创建新事务
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 空挂起,因为当前不存在事务
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
}
try {
// 创建新事务
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
// 事务传播属性设置为其它类型,即:PROPAGATION_SUPPORTS或者PROPAGATION_NOT_SUPPORTED或者PROPAGATION_NEVER
// 这些类型不需要当前存在事务
else {
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
// 空事务时是否需要事务同步,默认为SYNCHRONIZATION_ALWAYS,表示需要
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
doGetTransaction()
由子类DataSourceTransactionManager
实现,代码如下:
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
// 是否允许还原点
txObject.setSavepointAllowed(isNestedTransactionAllowed());
// 根据当前持有的数据源找到连接资源
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
// 封装连接资源,false表示连接资源不是新创建的
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
事务存在的判断由子类DataSourceTransactionManager
实现,代码如下:
protected boolean isExistingTransaction(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
// 当前记录的连接不为空,且连接的事务有效
return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}
当前是否存在事务会影响后续逻辑,所以需要分两种情况处理;
当前已存在事务
处理逻辑如下:
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// 事务传播属性设置为PROPAGATION_NEVER,表示不需要事务,但此时存在事务,需要抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
// 事务传播属性设置为PROPAGATION_NOT_SUPPORTED,表示不支持事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
// 挂起当前事务
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
// 准备事务状态,等本次操作结束后再恢复之前挂起事务
return prepareTransactionStatus(
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
// 事务传播属性设置为PROPAGATION_REQUIRES_NEW,表示需要新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
// 挂起当前事务,当新事务结束后,再恢复当前事务
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
// 创建新事务
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
// 事务传播属性设置为PROPAGATION_NESTED,表示在当前事务下嵌套进行,支持还原点设置
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 当前是否允许嵌套事务
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
// 是否可以使用还原点
if (useSavepointForNestedTransaction()) {
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
// 创建还原点,这样嵌套事务异常可以不导致当前事务回滚
status.createAndHoldSavepoint();
return status;
}
else {
// 不支持还原点设置的话,那么就需要创建新事务
// JTA不支持还原点设置
return startTransaction(definition, transaction, debugEnabled, null);
}
}
// 此时,事务传播属性设置为PROPAGATION_SUPPORTS或者PROPAGATION_REQUIRED,表示可以在当前事务下进行
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
// 是否需要校验当前存在的事务
if (isValidateExistingTransaction()) {
// 校验当前事务
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
// 获取事务同步标识
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
挂起事务实现如下:
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// 当前线程存在事务同步信息
// 缓存并挂起当前线程存在的事务同步信息
List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
try {
Object suspendedResources = null;
if (transaction != null) {
// 挂起当前事务
suspendedResources = doSuspend(transaction);
}
// 缓存并清空当前线程的事务同步管理器信息
String name = TransactionSynchronizationManager.getCurrentTransactionName();
TransactionSynchronizationManager.setCurrentTransactionName(null);
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
TransactionSynchronizationManager.setActualTransactionActive(false);
// 根据当前存在的事务信息、事务同步信息、事务同步管理器信息创建SuspendedResourcesHolder,便于后续恢复
return new SuspendedResourcesHolder(
suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
}
catch (RuntimeException | Error ex) {
doResumeSynchronization(suspendedSynchronizations);
throw ex;
}
}
// 当前线程不存在事务同步信息
else if (transaction != null) {
// 直接挂起当前事务
Object suspendedResources = doSuspend(transaction);
// 根据当前存在的事务信息创建SuspendedResourcesHolder,便于后续恢复事务
return new SuspendedResourcesHolder(suspendedResources);
}
else {
// 无事务需挂起,则没必要缓存事务信息
return null;
}
}
准备事务状态实现如下:
protected final DefaultTransactionStatus prepareTransactionStatus(
TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
// 基于已有的事务信息,构建事务状态
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
// 准备事务同步信息
prepareSynchronization(status, definition);
return status;
}
protected DefaultTransactionStatus newTransactionStatus(
TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
// 是否开启新事务同步
boolean actualNewSynchronization = newSynchronization &&
!TransactionSynchronizationManager.isSynchronizationActive();
return new DefaultTransactionStatus(
transaction, newTransaction, actualNewSynchronization,
definition.isReadOnly(), debug, suspendedResources);
}
/**
* 将事务同步信息记录到当前线程中
*/
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
definition.getIsolationLevel() : null);
// 设置事务只读标识
TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
TransactionSynchronizationManager.initSynchronization();
}
}
创建新事务实现如下:
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
// 构建事务状态
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
// 开启新事务
doBegin(transaction, definition);
// 准备事务同步信息
prepareSynchronization(status, definition);
return status;
}
开启新事务的真正操作由子类DataSourceTransactionManager
实现,代码如下:
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
// 当前不存在连接资源,或者当前连接资源的事务同步标识为true,才需要创建新连接
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
// 创建新连接
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
// 封装新连接资源,true表示连接资源是新创建的
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
// 设置连接资源和事务同步标识
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
// 获取连接
con = txObject.getConnectionHolder().getConnection();
// 根据事务属性配置当前连接,比如:只读属性、隔离级别
// 只针对当前连接
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 设置只读标识
txObject.setReadOnly(definition.isReadOnly());
// 如果连接是自动提交,则更改为由Spring手动提交
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
// 准备事务连接
// 此处会根据数据库的enforceReadOnly标识和事务的只读标识,选择执行"SET TRANSACTION READ ONLY"
prepareTransactionalConnection(con, definition);
// 设置连接的事务有效标识
// 判断当前线程是否存在事务会依赖该标识
txObject.getConnectionHolder().setTransactionActive(true);
// 设置事务超时信息
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// 如果是新创建的连接,则绑定到当前线程
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
catch (Throwable ex) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
当前不存在事务
分三种情况进行处理,如下:
- 事务传播属性设置为
PROPAGATION_MANDATORY
,表示当前不存在事务就需要抛出异常; - 事务传播属性设置为
PROPAGATION_REQUIRED
或者PROPAGATION_REQUIRES_NEW
或者PROPAGATION_NESTED
,表示需要创建新事务; - 事务传播属性设置为
PROPAGATION_SUPPORTS
或者PROPAGATION_NOT_SUPPORTED
或者PROPAGATION_NEVER
,表示不需要当前存在事务;
1. 事务传播属性设置为PROPAGATION_MANDATORY
表示当前不存在事务就需要抛出异常,因为此时线程不存在事务,所以直接抛出IllegalTransactionStateException
异常,代码如下:
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
2. 事务传播属性设置为PROPAGATION_REQUIRED
或者PROPAGATION_REQUIRES_NEW
或者PROPAGATION_NESTED
表示需要创建新事务,会先挂起当前事务(空事务),然后创建新事务,代码如下:
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 挂起当前空事务
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
}
try {
// 创建新事务
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
// 出现异常,则恢复原事务状态
resume(null, suspendedResources);
throw ex;
}
}
protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
throws TransactionException {
if (resourcesHolder != null) {
Object suspendedResources = resourcesHolder.suspendedResources;
// 存在事务信息,则恢复
if (suspendedResources != null) {
doResume(transaction, suspendedResources);
}
List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
// 存在事务同步信息,则恢复
if (suspendedSynchronizations != null) {
TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
doResumeSynchronization(suspendedSynchronizations);
}
}
}
doResume
由子类DataSourceTransactionManager
实现,代码如下:
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
// 绑定原连接资源
TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}
3. 事务传播属性设置为PROPAGATION_SUPPORTS
或者PROPAGATION_NOT_SUPPORTED
或者PROPAGATION_NEVER
表示不需要当前存在事务,那么直接准备事务状态即可,代码如下:
else {
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
准备事务信息
TransactionInfo
中不仅存在TransactionAttribute
,还存在TransactionStatus
,代码如下:
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {
// 基于事务管理器、事务属性、方法标识符构建事务信息
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
if (txAttr != null) {
// 事务属性存在,说明存在事务
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
// 设置事务状态
txInfo.newTransactionStatus(status);
}
else {
// 事务属性不存在,说明不存在事务
if (logger.isTraceEnabled()) {
logger.trace("No need to create transaction for [" + joinpointIdentification +
"]: This method is not transactional.");
}
}
// 绑定事务信息到当前线程
txInfo.bindToThread();
return txInfo;
}
private void bindToThread() {
this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);
}
回滚事务
在事务下执行操作过程中发生异常,则进入异常回滚处理,根据发生的异常类型选择性回滚事务,代码如下:
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
// 存在事务且异常类型满足回滚要求
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
// 回滚事务
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
}
else {
// 事务不存在,或者异常类型不满足回滚要求
try {
// 提交事务
// 如果TransactionStatus.isRollbackOnly()有效,那么也会回滚事务
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
回滚条件
在介绍获取事务属性时,提到事务属性默认是由SpringTransactionAnnotationParser
完成解析的,解析结果为RuleBasedTransactionAttribute
,其rollback
方法实现如下:
public boolean rollbackOn(Throwable ex) {
RollbackRuleAttribute winner = null;
int deepest = Integer.MAX_VALUE;
// 找到匹配的异常中最上层的异常
if (this.rollbackRules != null) {
for (RollbackRuleAttribute rule : this.rollbackRules) {
int depth = rule.getDepth(ex);
if (depth >= 0 && depth < deepest) {
deepest = depth;
winner = rule;
}
}
}
// 如果未匹配到异常,则调用父类DefaultTransactionAttribute的实现
if (winner == null) {
return super.rollbackOn(ex);
}
return !(winner instanceof NoRollbackRuleAttribute);
}
父类DefaultTransactionAttribute
的rollbackOn
实现如下:
public boolean rollbackOn(Throwable ex) {
// 如果是RuntimeException或者是Error
// 其它异常Spring认为需要由用户拦截处理
return (ex instanceof RuntimeException || ex instanceof Error);
}
回滚处理
满足回滚条件后,就会由事务管理器进行事务回滚,AbstractPlatformTransactionManager
实现了回滚逻辑,代码如下:
public final void rollback(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
// 如果事务已结束,则抛出IllegalTransactionStateException异常
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// 回滚事务,false表示此次回滚是预期中的
processRollback(defStatus, false);
}
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
// 完成前触发
triggerBeforeCompletion(status);
if (status.hasSavepoint()) {
// 存在还原点
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
// 回滚到还原点
status.rollbackToHeldSavepoint();
}
else if (status.isNewTransaction()) {
// 是新事务
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
// 回滚事务
doRollback(status);
}
else {
// 基于外部事务进行的,不是独立的事务,那么只能标记rollbackOnly标识,等到外部事务提交时再做回滚
// 当前是否存在外部事务
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
// 设置rollbackOnly标识
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
doSetRollbackOnly(status);
}
else {
// 不影响外部事务
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
}
else {
// 当前不存在外部事务,即没有事务
logger.debug("Should roll back transaction but cannot - no transaction available");
}
// 如果全局rollbackOnly有效时不提前失败,那么重置意外回滚标识
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
}
catch (RuntimeException | Error ex) {
// 发生异常,则完成后触发
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
// 完成后触发
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// 设置全局rollbackOnly标识,发生了意外回滚,则抛出UnexpectedRollbackException异常
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
}
finally {
// 完成后清除事务状态并恢复之前挂起的事务
cleanupAfterCompletion(status);
}
}
回滚处理分三种情况:
- 存在还原点,那么直接回滚到还原点;
- 是新事务,那么直接回滚事务;
- 当前存在外部事务,但又不属于以上两种情况,多用于JTA,那么只会标识rollbackOnly标识,等外部事务提交时统一处理;
1. 存在还原点
status.rollbackToHeldSavepoint()
由AbstractTransactionStatus
实现,代码如下:
public void rollbackToHeldSavepoint() throws TransactionException {
Object savepoint = getSavepoint();
if (savepoint == null) {
throw new TransactionUsageException(
"Cannot roll back to savepoint - no savepoint associated with current transaction");
}
// 回滚到还原点
getSavepointManager().rollbackToSavepoint(savepoint);
// 释放还原点
getSavepointManager().releaseSavepoint(savepoint);
// 清除还原点
setSavepoint(null);
}
如果使用的是数据库,那么getSavepointManager()
为JdbcTransactionObjectSupport
,其rollbackToSavepoint(savepoint)
实现如下:
public void rollbackToSavepoint(Object savepoint) throws TransactionException {
ConnectionHolder conHolder = getConnectionHolderForSavepoint();
try {
// 结束连接实现回滚到还原点
conHolder.getConnection().rollback((Savepoint) savepoint);
// 重置rollbackOnly标识
conHolder.resetRollbackOnly();
}
catch (Throwable ex) {
throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex);
}
}
2. 是新事务
doRollback
由子类DataSourceTransactionManager
实现,代码如下:
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
// 获取当前事务绑定的连接
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
// 回滚
con.rollback();
}
catch (SQLException ex) {
throw translateException("JDBC rollback", ex);
}
}
3. 其它情况
doSetRollbackOnly
由子类DataSourceTransactionManager
实现,代码如下:
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +
"] rollback-only");
}
// 设置rollbackOnly标识
txObject.setRollbackOnly();
}
回滚后处理
不论事务回滚执行是否成功后,都需要做收尾工作,代码如下:
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
// 设置事务完成标识
status.setCompleted();
if (status.isNewSynchronization()) {
// 清除同步信息
TransactionSynchronizationManager.clear();
}
if (status.isNewTransaction()) {
// 清除事务信息
doCleanupAfterCompletion(status.getTransaction());
}
if (status.getSuspendedResources() != null) {
// 存在挂起事务
if (status.isDebug()) {
logger.debug("Resuming suspended transaction after completion of inner transaction");
}
Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
// 恢复被挂起的事务
resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
}
}
doCleanupAfterCompletion
由子类DataSourceTransactionManager
实现,代码如下:
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
if (txObject.isNewConnectionHolder()) {
// 解绑数据库连接资源
TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (txObject.isMustRestoreAutoCommit()) {
// 恢复自动提交
con.setAutoCommit(true);
}
// 重置数据库连接
DataSourceUtils.resetConnectionAfterTransaction(
con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());
}
catch (Throwable ex) {
logger.debug("Could not reset JDBC Connection after transaction", ex);
}
if (txObject.isNewConnectionHolder()) {
if (logger.isDebugEnabled()) {
logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
}
// 释放数据库连接如果需要的话
DataSourceUtils.releaseConnection(con, this.dataSource);
}
// 清除持有连接资源信息
txObject.getConnectionHolder().clear();
}
提交事务
在事务下执行的操作正常结束了,则可以提交事务,代码如下:
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
// 存在事务,则提交事务
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
在事务回滚中,提到回滚处理会分三种情况,具体如下:
- 存在还原点;
- 是新事务;
- 当前存在外部事务,但又不属于以上两种情况,多用于JTA;
第三种情况下,只会标识rollbackOnly标识,等外部事务提交时统一处理,所以在事务提交处理中,需要判断事务是否被设置了rollbackOnly标识;
AbstractPlatformTransactionManager
实现了事务提交逻辑,代码如下:
public final void commit(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {
// 如果事务已结束,则抛出IllegalTransactionStateException异常
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
if (defStatus.isLocalRollbackOnly()) {
// 当前事务rollbackOnly标识有效,则进行回滚事务
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
// 回滚事务,false表示此次回滚是预期中的
processRollback(defStatus, false);
return;
}
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
// 如果全局rollbackOnly标识有效,且设置这种情况不进行事务提交
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
// 那就回滚事务,true表示此次回滚是预期外的
processRollback(defStatus, true);
return;
}
// 提交事务
processCommit(defStatus);
}
当事务执行一切正常,没有被设置rollbackOnly
标识,那么就进入事务提交处理,代码如下:
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
boolean unexpectedRollback = false;
// 提交前准备
prepareForCommit(status);
// 提交前触发
triggerBeforeCommit(status);
// 完成前触发
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
if (status.hasSavepoint()) {
// 存在还原点
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
unexpectedRollback = status.isGlobalRollbackOnly();
// 释放还原点
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
// 新事务
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
unexpectedRollback = status.isGlobalRollbackOnly();
// 提交事务
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = status.isGlobalRollbackOnly();
}
// 设置全局rollbackOnly标识,发生了意外回滚,则抛出UnexpectedRollbackException异常
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction silently rolled back because it has been marked as rollback-only");
}
}
catch (UnexpectedRollbackException ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
throw ex;
}
catch (TransactionException ex) {
if (isRollbackOnCommitFailure()) {
doRollbackOnCommitException(status, ex);
}
else {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
}
throw ex;
}
catch (RuntimeException | Error ex) {
// 提交过程中发生RuntimeException或者Error,则回滚事务
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
// 提交时异常,回滚事务
doRollbackOnCommitException(status, ex);
throw ex;
}
try {
// 提交后触发
triggerAfterCommit(status);
}
finally {
// 完成后触发
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
// 完成后清除事务状态
cleanupAfterCompletion(status);
}
}
提交处理分俩种情况:
- 存在还原点,那么直接释放还原点;
- 是新事务,那么直接提交事务;
1. 存在还原点
status.releaseHeldSavepoint()
由AbstractTransactionStatus
实现,代码如下:
public void releaseHeldSavepoint() throws TransactionException {
Object savepoint = getSavepoint();
if (savepoint == null) {
throw new TransactionUsageException(
"Cannot release savepoint - no savepoint associated with current transaction");
}
// 释放还原点
getSavepointManager().releaseSavepoint(savepoint);
// 清除还原点
setSavepoint(null);
}
2. 是新事务
doCommit
由子类DataSourceTransactionManager
实现,代码如下:
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
// 借助数据库连接完成提交
con.commit();
}
catch (SQLException ex) {
throw translateException("JDBC commit", ex);
}
}