第一节 参考
spring架构,Bean创建加载前的过程参考
第二节 架构
第三节 源码细节
一.@EnableTransactionManagement注解
springboot支持事务的注解.这个注解上面有@Import(TransactionManagementConfigurationSelector.class)注解标记.说明事务相关的处理类在TransactionManagementConfigurationSelector中注入.TransactionManagementConfigurationSelector类实现了ImportSelector接口.springboot中很多EnableXXX注解都实现了ImportSelector接口,这个接口在ConfigurationClassParser#processImports()方法中处理.spring在reresh()方法启动时,会进入AbstractApplicationContext#invokeBeanFactoryPostProcessors->ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry()->ConfigurationClassParser#parse()->ConfigurationClassParser#processImports()->TransactionManagementConfigurationSelector#selectImports(),启动堆栈如下图:
如上图,在这个方法里面返回导入ProxyTransactionManagementConfiguration配置类.
二.调用beanName为"transactionInterceptor"的getBean()时.
进入ProxyTransactionManagementConfiguration#transactionInterceptor().代码如下:
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
//我的数据源是通过springboot的yml文件配置.对应AnnotationTransactionAttributeSource类
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
这个TransactionInterceptor类处理事务的核心类,事务的代理对象进入TransactionInterceptor#invoke()拦截事务操作.
三.当创建带有@Transactional方法注解的类时.
getBean(),调用BeanPostProcessor#postProcessAfterInitialization()回调,依次经过调用链AbstractAutoProxyCreator#
postProcessAfterInitialization()->TransactionAttributeSourcePointcut#matches()->
AbstractFallbackTransactionAttributeSource#getTransactionAttribute()->AnnotationTransactionAttributeSource#
determineTransactionAttribute()方法,解析@Transactional注解的配置值.
四.@Transactional拦截事务操作
1.带有@Transactional注解方法的业务类代理对象,调用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);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
//调用实际完成事务处理的方法,代码如下
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
处理事务的核心方法,进入TransactionAspectSupport#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();
//获取AbstractFallbackTransactionAttributeSource#attributeCache成员缓存中目标方法的事务属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//获取事务管理器,方法在后面2处分析,默认获取到DataSourceTransactionManager
final TransactionManager tm = determineTransactionManager(txAttr);
//默认此处不进入
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.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(
method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}
//DataSourceTransactionManager类转成PlatformTransactionManager接口,这个接口结构在后面代码3处
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
//返回当前带有@Transactional注解的方法全路径
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
//txAttr是RuleBasedTransactionAttribute类型对象不为null.这里满足第二个条件,进入if内
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//调用AbstractPlatformTransactionManager#getTransaction()获取事务对象,代码在下面分析
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//调用业务方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//出现异常,调用PlatformTransactionManager#rollback()回退事务,向上层调用抛出异常
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//设置threadlocal中的TransactionAspectSupport#transactionInfoHolder事务信息未null
cleanupTransactionInfo(txInfo);
}
...
//事务正常执行,调用PlatformTransactionManager#commit()提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
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;
}
}
}
创建事务,进入TransactionAspectSupport#createTransactionIfNecessary(),代码如下:
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
...
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//创建事务,在下面的4处分析
status = tm.getTransaction(txAttr);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
//把事务对象添加TransactionAspectSupport#transactionInfoHolder成员中,这是个ThreadLocal
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
2.获取事务管理器
进入TransactionAspectSupport#determineTransactionManager()方法.代码如下:
protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
// Do not attempt to lookup tx manager if no tx attributes are set
if (txAttr == null || this.beanFactory == null) {
return getTransactionManager();
}
//获取@Transactional注解上的值.一般不加配置项,就得到空串
String qualifier = txAttr.getQualifier();
if (StringUtils.hasText(qualifier)) {
return determineQualifiedTransactionManager(this.beanFactory, qualifier);
}
else if (StringUtils.hasText(this.transactionManagerBeanName)) {
return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
}
else {
//默认进入到这里面.
TransactionManager defaultTransactionManager = getTransactionManager();
//默认获取到null
if (defaultTransactionManager == null) {
defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
if (defaultTransactionManager == null) {
/* 获取bean工厂中的事务管理器,默认是DataSourceTransactionManager类.事务管理器做具体的事务的begin,commit,
rollback操作 */
defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
this.transactionManagerCache.putIfAbsent(
DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
}
}
return defaultTransactionManager;
}
}
3.事务管理器接口及虚拟实现类
TransactionManager是个空接口.
public interface PlatformTransactionManager extends TransactionManager {
/**
* Return a currently active transaction or create a new one, according to
* the specified propagation behavior.
* Note that parameters like isolation level or timeout will only be applied
* to new transactions, and thus be ignored when participating in active ones.
*
Furthermore, not all transaction definition settings will be supported
* by every transaction manager: A proper transaction manager implementation
* should throw an exception when unsupported settings are encountered.
*
An exception to the above rule is the read-only flag, which should be
* ignored if no explicit read-only mode is supported. Essentially, the
* read-only flag is just a hint for potential optimization.
* @param definition the TransactionDefinition instance (can be {@code null} for defaults),
* describing propagation behavior, isolation level, timeout etc.
* @return transaction status object representing the new or current transaction
* @throws TransactionException in case of lookup, creation, or system errors
* @throws IllegalTransactionStateException if the given transaction definition
* cannot be executed (for example, if a currently active transaction is in
* conflict with the specified propagation behavior)
* @see TransactionDefinition#getPropagationBehavior
* @see TransactionDefinition#getIsolationLevel
* @see TransactionDefinition#getTimeout
* @see TransactionDefinition#isReadOnly
*/
//获取事务
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException;
/**
* Commit the given transaction, with regard to its status. If the transaction
* has been marked rollback-only programmatically, perform a rollback.
*
If the transaction wasn't a new one, omit the commit for proper
* participation in the surrounding transaction. If a previous transaction
* has been suspended to be able to create a new one, resume the previous
* transaction after committing the new one.
*
Note that when the commit call completes, no matter if normally or
* throwing an exception, the transaction must be fully completed and
* cleaned up. No rollback call should be expected in such a case.
*
If this method throws an exception other than a TransactionException,
* then some before-commit error caused the commit attempt to fail. For
* example, an O/R Mapping tool might have tried to flush changes to the
* database right before commit, with the resulting DataAccessException
* causing the transaction to fail. The original exception will be
* propagated to the caller of this commit method in such a case.
* @param status object returned by the {@code getTransaction} method
* @throws UnexpectedRollbackException in case of an unexpected rollback
* that the transaction coordinator initiated
* @throws HeuristicCompletionException in case of a transaction failure
* caused by a heuristic decision on the side of the transaction coordinator
* @throws TransactionSystemException in case of commit or system errors
* (typically caused by fundamental resource failures)
* @throws IllegalTransactionStateException if the given transaction
* is already completed (that is, committed or rolled back)
* @see TransactionStatus#setRollbackOnly
*/
//提交事务
void commit(TransactionStatus status) throws TransactionException;
/**
* Perform a rollback of the given transaction.
*
If the transaction wasn't a new one, just set it rollback-only for proper
* participation in the surrounding transaction. If a previous transaction
* has been suspended to be able to create a new one, resume the previous
* transaction after rolling back the new one.
*
Do not call rollback on a transaction if commit threw an exception.
* The transaction will already have been completed and cleaned up when commit
* returns, even in case of a commit exception. Consequently, a rollback call
* after commit failure will lead to an IllegalTransactionStateException.
* @param status object returned by the {@code getTransaction} method
* @throws TransactionSystemException in case of rollback or system errors
* (typically caused by fundamental resource failures)
* @throws IllegalTransactionStateException if the given transaction
* is already completed (that is, committed or rolled back)
*/
//回滚事务
void rollback(TransactionStatus status) throws TransactionException;
}
4.获取事务对象
进入AbstractPlatformTransactionManager#getTransaction(),当前对象由DataSourceTransactionManager继承而来.代码如下:
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// Use defaults if no transaction definition given.
//获取目标方法的事务属性值.
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
//代码在下面分析,返回DataSourceTransactionManager.DataSourceTransactionObject内部类对象.
Object transaction = doGetTransaction();
boolean debugEnabled = logger.isDebugEnabled();
//进入目标方法前是否已经存在事务.
if (isExistingTransaction(transaction)) {
// Existing transaction found -> check propagation behavior to find out how to behave.
//如果已经存在事务,根据传播属性判断是否新建事务,还是沿用旧事物,代码在后面5分析
return handleExistingTransaction(def, transaction, debugEnabled);
}
// Check definition settings for new transaction.
//事务是否超时,TIMEOUT_DEFAULT默认为-1,不会超时.
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
// No existing transaction found -> check propagation behavior to find out how to proceed.
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
//默认是PROPAGATION_REQUIRED级别
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 {
//开始事务,代码在后面6处分析
return startTransaction(def, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
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);
}
}
获取事务对象,进入DataSourceTransactionManager#doGetTransaction()方法,代码如下:
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//获取配置文件中配置的数据源,即mysql的ip,端口号,用户名,密码等
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
5.处理事务的传播属性.
进入AbstractPlatformTransactionManager#handleExistingTransaction()方法,进入这个方法前,即进入目标方法之前,
已经存在事务。代码如下:
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//如果目标方法配置不能有事务,抛异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//如果目标方法配置不支持事务,挂起当前事务
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);
}
//如果目标方法需要新事务,开启新事务
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;
}
}
//如果目标方法需要嵌套事务,使用保存点保存之前的事务.创建新事务
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()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
return startTransaction(definition, transaction, debugEnabled, null);
}
}
// Assumably PROPAGATION_SUPPORTS or 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);
}
6.开始事务.从上面4调用过来.
进入方法AbstractPlatformTransactionManager#startTransaction(),代码如下:
private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
//创建DefaultTransactionStatus对象
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//在下面分析
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
进入方法DataSourceTransactionManager#doBegin()方法,开始事务.
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
//获取jdbc连接
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
//获取事务定义的隔离级别
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
// so we don't want to do it unnecessarily (for example if we've explicitly
// configured the connection pool to set it already).
//设置事务不要自动提交
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
...
}
catch (Throwable ex) {
...
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}