摘要
Spring事务通过AOP代理、事务管理器、同步机制等组件提供了强大而灵活的事务管理能力。本文将重点剖析事务传播机制的实现原理,包括事务管理器的架构、AOP代理原理、事务同步机制、传播行为实现细节等核心概念。
1. Spring事务架构概述
1.1 事务管理核心接口体系
Spring事务管理建立在三个核心接口之上,这些接口构成了整个事务管理体系的抽象层:
java
// 事务管理器接口 - 定义事务的基本操作
public interface PlatformTransactionManager {
// 根据事务定义获取事务状态
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交事务
void commit(TransactionStatus status) throws TransactionException;
// 回滚事务
void rollback(TransactionStatus status) throws TransactionException;
}
// 事务定义接口 - 定义事务的基本属性
public interface TransactionDefinition {
// 传播行为常量
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
// 隔离级别常量
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 3;
int ISOLATION_SERIALIZABLE = 4;
// 超时时间常量
int TIMEOUT_DEFAULT = -1;
// 获取传播行为
int getPropagationBehavior();
// 获取隔离级别
int getIsolationLevel();
// 获取超时时间
int getTimeout();
// 是否只读
boolean isReadOnly();
// 获取事务名称
String getName();
}
// 事务状态接口 - 表示事务的当前状态
public interface TransactionStatus extends SavepointManager, Flushable {
// 是否是新事务
boolean isNewTransaction();
// 是否有保存点
boolean hasSavepoint();
// 设置为仅回滚
void setRollbackOnly();
// 是否标记为仅回滚
boolean isRollbackOnly();
// 是否已完成
boolean isCompleted();
}
1.2 事务管理器实现层次结构
Spring提供了多种事务管理器实现,形成了清晰的继承体系:
java
// 抽象事务管理器 - 实现通用的事务管理逻辑
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager {
// 事务同步策略
public static final int SYNCHRONIZATION_ALWAYS = 0;
public static final int SYNCHRONIZATION_ON_ACTUAL_TRANSACTION = 1;
public static final int SYNCHRONIZATION_NEVER = 2;
// 事务同步策略
private int transactionSynchronization = SYNCHRONIZATION_ON_ACTUAL_TRANSACTION;
// 默认超时时间
private int defaultTimeout = TransactionDefinition.TIMEOUT_DEFAULT;
// 是否在参与失败时全局回滚
private boolean globalRollbackOnParticipationFailure = true;
// 是否在提交失败时回滚
private boolean rollbackOnCommitFailure = true;
// 是否验证现有事务
private boolean validateExistingTransaction = true;
// 核心事务获取方法
@Override
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
// 1. 获取底层事务对象
Object transaction = doGetTransaction();
// 2. 缓存调试标志
boolean debugEnabled = logger.isDebugEnabled();
// 3. 如果没有事务定义,使用默认定义
if (definition == null) {
definition = new DefaultTransactionDefinition();
}
// 4. 检查是否已存在事务
if (isExistingTransaction(transaction)) {
// 处理已存在事务的情况(根据传播行为)
return handleExistingTransaction(definition, transaction, debugEnabled);
}
// 5. 检查传播行为
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
// 挂起任何现有事务
SuspendedResourcesHolder suspendedResources = suspend(null);
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
}
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
transaction, true, newSynchronization, definition.getIsolationLevel(), debugEnabled, suspendedResources);
// 开始事务
doBegin(transaction, definition);
// 准备同步
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error ex) {
// 开始失败时恢复挂起的事务
resume(null, suspendedResources);
throw ex;
}
}
else {
// PROPAGATION_SUPPORTS 或 PROPAGATION_NOT_SUPPORTED 或 PROPAGATION_NEVER
if (debugEnabled) {
logger.debug("Non-transactional execution with propagation '" +
definition.getPropagationBehavior() + "' on: " + definition);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(transaction, false, newSynchronization, definition.getIsolationLevel(), debugEnabled);
}
}
// 处理已存在事务的情况
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// 根据传播行为处理
switch (definition.getPropagationBehavior()) {
case TransactionDefinition.PROPAGATION_NEVER:
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
case TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
// 挂起现有事务,以非事务方式执行
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
return prepareTransactionStatus(
null, false, newSynchronization, definition.getIsolationLevel(), debugEnabled, suspendedResources);
case TransactionDefinition.PROPAGATION_REQUIRES_NEW:
// 挂起现有事务,创建新事务
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
transaction, true, newSynchronization, definition.getIsolationLevel(), debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
case 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(transaction, false, false, definition.getIsolationLevel(), debugEnabled);
status.createAndHoldSavepoint();
return status;
}
else {
// 使用真正的嵌套事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
transaction, true, newSynchronization, definition.getIsolationLevel(), debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
case TransactionDefinition.PROPAGATION_SUPPORTS:
case TransactionDefinition.PROPAGATION_REQUIRED:
case TransactionDefinition.PROPAGATION_MANDATORY:
// 默认情况:加入现有事务
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(transaction, false, newSynchronization, definition.getIsolationLevel(), debugEnabled);
default:
throw new IllegalTransactionStateException("Unknown propagation behavior: " + definition.getPropagationBehavior());
}
}
}
1.3 数据源事务管理器实现
DataSourceTransactionManager是Spring中最常用的事务管理器实现,它管理JDBC连接的事务:
java
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
private DataSource dataSource;
// 事务对象,封装连接持有者
private static class DataSourceTransactionObject extends JdbcTransactionObjectSupport {
private boolean newConnectionHolder;
private boolean mustRestoreAutoCommit;
private Integer previousIsolationLevel;
public void setConnectionHolder(ConnectionHolder connectionHolder, boolean newConnectionHolder) {
super.setConnectionHolder(connectionHolder);
this.newConnectionHolder = newConnectionHolder;
}
public boolean isNewConnectionHolder() {
return this.newConnectionHolder;
}
public void setMustRestoreAutoCommit(boolean mustRestoreAutoCommit) {
this.mustRestoreAutoCommit = mustRestoreAutoCommit;
}
public boolean isMustRestoreAutoCommit() {
return this.mustRestoreAutoCommit;
}
public void setPreviousIsolationLevel(Integer previousIsolationLevel) {
this.previousIsolationLevel = previousIsolationLevel;
}
public Integer getPreviousIsolationLevel() {
return this.previousIsolationLevel;
}
public boolean hasConnectionHolder() {
return (getConnectionHolder() != null);
}
}
@Override
protected Object doGetTransaction() {
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
// 从线程上下文中获取当前连接持有者
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
@Override
protected boolean isExistingTransaction(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
Connection con = null;
try {
// 1. 如果没有现有连接,从数据源获取新连接
if (!txObject.hasConnectionHolder() ||
txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = obtainDataSource().getConnection();
if (logger.isDebugEnabled()) {
logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
// 2. 绑定连接持有者到当前线程
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
txObject.getConnectionHolder().setTransactionActive(true);
// 3. 设置事务隔离级别和只读状态
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(
txObject.getConnectionHolder(), definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
// 4. 设置自动提交为false(开启事务)
Connection conToUse = txObject.getConnectionHolder().getConnection();
if (conToUse.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (logger.isDebugEnabled()) {
logger.debug("Switching JDBC Connection [" + conToUse + "] to manual commit");
}
conToUse.setAutoCommit(false);
}
// 5. 准备事务连接持有者
prepareTransactionalConnection(conToUse, definition);
txObject.getConnectionHolder().setTransactionActive(true);
// 6. 绑定数据源和连接持有者到同步管理器
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
// 7. 绑定连接持有者到当前线程
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
}
}
catch (SQLException ex) {
// 异常处理:释放连接
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, obtainDataSource());
txObject.setConnectionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
// 提交事务
con.commit();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not commit JDBC transaction", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
// 回滚事务
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
@Override
protected void doSetRollbackOnly(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + "] rollback-only");
}
txObject.getConnectionHolder().setRollbackOnly();
}
@Override
protected void doCleanupAfterCompletion(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
// 1. 解绑连接持有者
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
// 2. 重置连接状态
Connection con = txObject.getConnectionHolder().getConnection();
try {
if (txObject.isMustRestoreAutoCommit()) {
con.setAutoCommit(true);
}
DataSourceUtils.resetConnectionAfterTransaction(
con, txObject.getPreviousIsolationLevel());
}
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, obtainDataSource());
}
// 3. 清理连接持有者
txObject.getConnectionHolder().clear();
}
}
2. Spring事务AOP实现机制
2.1 事务代理创建过程
Spring通过InfrastructureAdvisorAutoProxyCreator自动创建事务代理,这是Spring基础设施自动代理机制的一部分:
java
@Configuration
@EnableTransactionManagement
public class TransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
BeanFactoryTransactionAttributeSourceAdvisor是一个Spring AOP Advisor,它结合了事务属性源和事务拦截器:
java
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
// 事务属性源切点
private abstract static class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
@Override
public boolean equals(Object other) {
return (this == other || (other instanceof TransactionAttributeSourcePointcut &&
Objects.equals(getTransactionAttributeSource(), ((TransactionAttributeSourcePointcut) other).getTransactionAttributeSource())));
}
@Override
public int hashCode() {
return TransactionAttributeSourcePointcut.class.hashCode();
}
@Override
public String toString() {
return getClass().getName() + ": " + getTransactionAttributeSource();
}
protected abstract TransactionAttributeSource getTransactionAttributeSource();
}
}
2.2 事务拦截器核心逻辑
TransactionInterceptor是Spring事务的核心拦截器,它实现了MethodInterceptor接口:
java
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
public TransactionInterceptor() {
setTransactionAttributeSource(new AnnotationTransactionAttributeSource());
}
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
// 获取目标类
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// 适配到事务方法调用
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}
TransactionAspectSupport提供了事务拦截的核心逻辑:
java
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// 1. 获取事务属性
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 2. 获取事务管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 3. 构造连接点标识(用于日志)
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 4. 声明式事务处理
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// 标准事务:获取事务,执行目标方法,提交/回滚
TransactionInfo txInfo = 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;
}
else {
// 编程式事务处理
final ThrowableHolder throwableHolder = new ThrowableHolder();
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
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 (RuntimeException | Error ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
}
}
// 创建事务信息
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// 1. 如果没有指定名称,使用方法标识作为事务名称
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) {
// 2. 获取事务
status = tm.getTransaction(txAttr);
}
else {
// 3. 非事务环境
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
// 4. 创建事务信息并绑定到线程
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
// 准备事务信息
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 Spring transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
}
// 绑定事务信息到当前线程
txInfo.bindToThread();
return txInfo;
}
// 异常处理
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 {
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;
}
}
}
}
// 提交事务
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());
}
}
// 清理事务信息
protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {
if (txInfo != null) {
txInfo.restoreThreadLocalStatus();
}
}
// 事务信息内部类
protected static 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;
}
public String getJoinpointIdentification() {
return this.joinpointIdentification;
}
public void newTransactionStatus(@Nullable TransactionStatus status) {
this.transactionStatus = status;
}
@Nullable
public TransactionStatus getTransactionStatus() {
return this.transactionStatus;
}
public void bindToThread() {
this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);
}
public void restoreThreadLocalStatus() {
transactionInfoHolder.set(this.oldTransactionInfo);
}
@Override
public String toString() {
return this.transactionAttribute.toString();
}
}
private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
new NamedThreadLocal<>("Current aspect-driven transaction");
}
3. 事务传播机制深度解析
3.1 事务传播行为概述
事务传播行为定义了事务方法被调用时事务边界的行为,Spring定义了7种传播行为:
- PROPAGATION_REQUIRED(默认):如果当前存在事务,则加入该事务;如果不存在,则创建一个新事务。
- PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果不存在,则以非事务方式执行。
- PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果不存在,则抛出异常。
- PROPAGATION_REQUIRES_NEW:创建一个新事务,如果当前存在事务,则挂起当前事务。
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行;如果不存在,则创建一个新事务。
3.2 事务传播行为实现原理
Spring事务传播行为的实现核心在AbstractPlatformTransactionManager.handleExistingTransaction方法中:
java
private TransactionStatus handleExistingTransaction(
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
// 根据传播行为处理
switch (definition.getPropagationBehavior()) {
case TransactionDefinition.PROPAGATION_NEVER:
// 不允许存在事务
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
case TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
// 挂起现有事务,以非事务方式执行
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ON_ACTUAL_TRANSACTION);
return prepareTransactionStatus(
null, false, newSynchronization, definition.getIsolationLevel(), debugEnabled, suspendedResources);
case TransactionDefinition.PROPAGATION_REQUIRES_NEW:
// 挂起现有事务,创建新事务
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
transaction, true, newSynchronization, definition.getIsolationLevel(), debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
case 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(transaction, false, false, definition.getIsolationLevel(), debugEnabled);
status.createAndHoldSavepoint();
return status;
}
else {
// 使用真正的嵌套事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
transaction, true, newSynchronization, definition.getIsolationLevel(), debugEnabled, null);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
case TransactionDefinition.PROPAGATION_SUPPORTS:
case TransactionDefinition.PROPAGATION_REQUIRED:
case TransactionDefinition.PROPAGATION_MANDATORY:
// 默认情况:加入现有事务
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(transaction, false, newSynchronization, definition.getIsolationLevel(), debugEnabled);
default:
throw new IllegalTransactionStateException("Unknown propagation behavior: " + definition.getPropagationBehavior());
}
}
3.3 事务挂起与恢复机制
事务挂起是事务传播行为中的关键机制,它允许在需要时暂停当前事务,执行其他操作,然后再恢复原事务:
java
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);
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);
return new SuspendedResourcesHolder(suspendedResources);
}
else {
// 没有事务和同步,返回空
return null;
}
}
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);
}
}
}
// 挂起资源的具体实现
@Override
protected Object doSuspend(Object transaction) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
txObject.setConnectionHolder(null);
return TransactionSynchronizationManager.unbindResource(obtainDataSource());
}
// 恢复资源的具体实现
@Override
protected void doResume(Object transaction, Object suspendedResources) {
TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}
// 挂起同步的具体实现
private List<TransactionSynchronization> doSuspendSynchronization() {
List<TransactionSynchronization> suspendedSynchronizations =
TransactionSynchronizationManager.getSynchronizations();
for (TransactionSynchronization synchronization : suspendedSynchronizations) {
synchronization.suspend();
}
TransactionSynchronizationManager.clearSynchronization();
return suspendedSynchronizations;
}
// 恢复同步的具体实现
private void doResumeSynchronization(List<TransactionSynchronization> suspendedSynchronizations) {
TransactionSynchronizationManager.initSynchronization();
for (TransactionSynchronization synchronization : suspendedSynchronizations) {
TransactionSynchronizationManager.registerSynchronization(synchronization);
synchronization.resume();
}
}
3.4 嵌套事务实现机制
Spring嵌套事务有两种实现方式:保存点和真正的嵌套事务:
java
// DefaultTransactionStatus中的保存点相关方法
public class DefaultTransactionStatus extends AbstractTransactionStatus {
@Nullable
private Object savepoint;
// 创建并持有保存点
public void createAndHoldSavepoint() throws TransactionException {
setSavepoint(getSavepointManager().createSavepoint());
}
// 回滚到保存点
public void rollbackToHeldSavepoint() throws TransactionException {
Object savepoint = getSavepoint();
if (savepoint == null) {
throw new TransactionUsageException(
"No savepoint associated with current transaction");
}
getSavepointManager().rollbackToSavepoint(savepoint);
getSavepointManager().releaseSavepoint(savepoint);
setSavepoint(null);
}
// 释放保存点
public void releaseHeldSavepoint() throws TransactionException {
Object savepoint = getSavepoint();
if (savepoint == null) {
throw new TransactionUsageException(
"No savepoint associated with current transaction");
}
getSavepointManager().releaseSavepoint(savepoint);
setSavepoint(null);
}
}
// DataSourceTransactionManager中的保存点管理
@Override
protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.hasSavepoint()) {
// 嵌套事务:回滚到保存点
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
try {
con.rollback((Savepoint) status.getSavepoint());
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex);
}
}
else if (txObject.isNewTransaction()) {
// 新事务:执行回滚
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
try {
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}
else if (txObject.hasConnectionHolder()) {
// 参与现有事务:设置回滚标记
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
txObject.getConnectionHolder().setRollbackOnly();
}
else {
if (logger.isDebugEnabled()) {
logger.debug("No transaction available for rollback");
}
}
}
3.5 事务传播行为实际应用场景
java
@Service
public class OrderService {
@Autowired
private PaymentService paymentService;
@Autowired
private InventoryService inventoryService;
@Autowired
private LogService logService;
@Autowired
private NotificationService notificationService;
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
// 1. 创建订单(在当前事务中)
orderRepository.save(order);
try {
// 2. 处理支付(REQUIRES_NEW:独立事务)
paymentService.processPayment(order);
// 3. 减少库存(REQUIRED:加入当前事务)
inventoryService.reduceStock(order);
// 4. 记录日志(NOT_SUPPORTED:非事务执行)
logService.logOrderCreation(order);
} catch (Exception e) {
// 支付或库存操作失败,订单创建也会回滚
throw new OrderCreationException("订单创建失败", e);
}
// 5. 发送通知(NEVER:不允许事务)
try {
notificationService.sendOrderNotification(order);
} catch (Exception e) {
// 通知失败不影响订单创建
logger.error("发送订单通知失败", e);
}
}
@Transactional(propagation = Propagation.NESTED)
public void createOrderWithNested(Order order) {
// 创建订单
orderRepository.save(order);
try {
// 减少库存(嵌套事务)
inventoryService.reduceStockWithNested(order);
} catch (Exception e) {
// 库存操作失败,只回滚库存操作,订单保留
throw new OrderCreationException("库存操作失败,订单已创建", e);
}
}
}
@Service
public class PaymentService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void processPayment(Order order) {
// 独立事务:无论调用方是否回滚,支付记录都会保留
paymentRepository.save(new Payment(order));
// 模拟支付失败
if (order.getAmount() > 1000) {
throw new PaymentException("支付金额超限");
}
}
}
@Service
public class InventoryService {
@Transactional(propagation = Propagation.REQUIRED)
public void reduceStock(Order order) {
// 加入当前事务:与订单创建在同一个事务中
inventoryRepository.reduceStock(order.getProductId(), order.getQuantity());
}
@Transactional(propagation = Propagation.NESTED)
public void reduceStockWithNested(Order order) {
// 嵌套事务:使用保存点实现
inventoryRepository.reduceStock(order.getProductId(), order.getQuantity());
// 模拟库存不足
if (order.getQuantity() > 100) {
throw new InventoryException("库存不足");
}
}
}
@Service
public class LogService {
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void logOrderCreation(Order order) {
// 非事务执行:无论调用方是否回滚,日志都会记录
logRepository.save(new OrderLog("订单创建", order.getId()));
}
}
@Service
public class NotificationService {
@Transactional(propagation = Propagation.NEVER)
public void sendOrderNotification(Order order) {
// 不允许事务:如果当前存在事务,抛出异常
notificationService.sendNotification("订单创建成功", order.getUserId());
}
}
4. 事务同步机制深度解析
4.1 TransactionSynchronizationManager核心机制
TransactionSynchronizationManager是Spring事务同步的核心管理器,负责管理事务资源和同步回调:
java
public abstract class TransactionSynchronizationManager {
// 线程本地变量,存储事务资源
private static final ThreadLocal<Map<Object, Object>> resources =
new NamedThreadLocal<>("Transactional resources");
// 线程本地变量,存储事务同步回调
private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
new NamedThreadLocal<>("Transaction synchronizations");
// 线程本地变量,存储当前事务名称
private static final ThreadLocal<String> currentTransactionName =
new NamedThreadLocal<>("Current transaction name");
// 线程本地变量,存储当前事务只读状态
private static final ThreadLocal<Boolean> currentTransactionReadOnly =
new NamedThreadLocal<>("Current transaction read-only status");
// 线程本地变量,存储当前事务隔离级别
private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
new NamedThreadLocal<>("Current transaction isolation level");
// 线程本地变量,存储当前事务活跃状态
private static final ThreadLocal<Boolean> actualTransactionActive =
new NamedThreadLocal<>("Actual transaction active");
// 绑定资源到当前线程
public static void bindResource(Object key, Object value) throws IllegalStateException {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Assert.notNull(value, "Value must not be null");
Map<Object, Object> map = resources.get();
if (map == null) {
map = new HashMap<>();
resources.set(map);
}
Object oldValue = map.put(actualKey, value);
if (oldValue != null) {
throw new IllegalStateException("Already value [" + oldValue + "] for key [" +
actualKey + "] bound to thread");
}
}
// 从当前线程解绑资源
public static Object unbindResource(Object key) throws IllegalStateException {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doUnbindResource(actualKey);
if (value == null) {
throw new IllegalStateException("No value for key [" + actualKey + "] bound to thread");
}
return value;
}
// 从当前线程解绑资源(不抛出异常)
@Nullable
public static Object unbindResourceIfPossible(Object key) {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
return doUnbindResource(actualKey);
}
// 实际解绑资源
@Nullable
private static Object doUnbindResource(Object actualKey) {
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
Object value = map.remove(actualKey);
if (map.isEmpty()) {
resources.remove();
}
if (value instanceof ResourceHolder) {
((ResourceHolder) value).unbound();
}
return value;
}
// 获取资源
@Nullable
public static Object getResource(Object key) {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
if (value != null && logger.isTraceEnabled()) {
logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread");
}
return value;
}
// 实际获取资源
@Nullable
private static Object doGetResource(Object actualKey) {
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
Object value = map.get(actualKey);
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
value = null;
}
return value;
}
// 检查是否有活跃同步
public static boolean isSynchronizationActive() {
return (synchronizations.get() != null);
}
// 初始化同步
public static void initSynchronization() throws IllegalStateException {
if (isSynchronizationActive()) {
throw new IllegalStateException("Cannot activate transaction synchronization - already active");
}
logger.trace("Initializing transaction synchronization");
synchronizations.set(new LinkedHashSet<>());
}
// 注册同步
public static void registerSynchronization(TransactionSynchronization synchronization)
throws IllegalStateException {
Assert.notNull(synchronization, "TransactionSynchronization must not be null");
if (!isSynchronizationActive()) {
throw new IllegalStateException("Transaction synchronization is not active");
}
synchronizations.get().add(synchronization);
}
// 获取所有同步
public static List<TransactionSynchronization> getSynchronizations() throws IllegalStateException {
Set<TransactionSynchronization> synchs = synchronizations.get();
if (synchs == null) {
throw new IllegalStateException("Transaction synchronization is not active");
}
if (synchs.isEmpty()) {
return Collections.emptyList();
}
else {
List<TransactionSynchronization> sortedSynchs = new ArrayList<>(synchs);
OrderComparator.sort(sortedSynchs);
return Collections.unmodifiableList(sortedSynchs);
}
}
// 清除同步
public static void clearSynchronization() throws IllegalStateException {
if (!isSynchronizationActive()) {
throw new IllegalStateException("Cannot deactivate transaction synchronization - not active");
}
logger.trace("Clearing transaction synchronization");
synchronizations.remove();
}
// 设置当前事务名称
public static void setCurrentTransactionName(@Nullable String name) {
currentTransactionName.set(name);
}
// 获取当前事务名称
@Nullable
public static String getCurrentTransactionName() {
return currentTransactionName.get();
}
// 设置当前事务只读状态
public static void setCurrentTransactionReadOnly(boolean readOnly) {
currentTransactionReadOnly.set(readOnly ? Boolean.TRUE : null);
}
// 检查当前事务是否只读
public static boolean isCurrentTransactionReadOnly() {
return (currentTransactionReadOnly.get() != null);
}
// 设置当前事务隔离级别
public static void setCurrentTransactionIsolationLevel(@Nullable Integer isolationLevel) {
currentTransactionIsolationLevel.set(isolationLevel);
}
// 获取当前事务隔离级别
@Nullable
public static Integer getCurrentTransactionIsolationLevel() {
return currentTransactionIsolationLevel.get();
}
// 设置当前事务活跃状态
public static void setActualTransactionActive(boolean active) {
actualTransactionActive.set(active ? Boolean.TRUE : null);
}
// 检查当前事务是否活跃
public static boolean isActualTransactionActive() {
return (actualTransactionActive.get() != null);
}
// 清除所有资源
public static void clear() {
resources.remove();
synchronizations.remove();
currentTransactionName.remove();
currentTransactionReadOnly.remove();
currentTransactionIsolationLevel.remove();
actualTransactionActive.remove();
}
}
4.2 事务同步回调机制
Spring事务同步回调机制允许在事务的不同阶段执行自定义逻辑:
java
public interface TransactionSynchronization extends Flushable {
// 完成状态枚举
enum Status {
COMMITTED, ROLLED_BACK, UNKNOWN
}
// 挂起回调
default void suspend() {
}
// 恢复回调
default void resume() {
}
// 刷新回调
@Override
default void flush() {
}
// 提交前回调
default void beforeCommit(boolean readOnly) {
}
// 完成前回调
default void beforeCompletion() {
}
// 提交后回调
default void afterCommit() {
}
// 完成后回调
default void afterCompletion(int status) {
}
// 获取执行顺序
default int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
// 事务同步触发器
public abstract class TransactionSynchronizationUtils {
// 触发挂起回调
public static void triggerSuspend() {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
synchronization.suspend();
}
}
// 触发恢复回调
public static void triggerResume() {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
synchronization.resume();
}
}
// 触发提交前回调
public static void triggerBeforeCommit(boolean readOnly) {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
synchronization.beforeCommit(readOnly);
}
}
// 触发完成前回调
public static void triggerBeforeCompletion() {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
try {
synchronization.beforeCompletion();
}
catch (Throwable tsex) {
logger.error("TransactionSynchronization.beforeCompletion threw exception", tsex);
}
}
}
// 触发提交后回调
public static void triggerAfterCommit() {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
try {
synchronization.afterCommit();
}
catch (Throwable tsex) {
logger.error("TransactionSynchronization.afterCommit threw exception", tsex);
}
}
}
// 触发完成后回调
public static void triggerAfterCompletion(int status) {
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
if (!synchronizations.isEmpty()) {
for (TransactionSynchronization synchronization : synchronizations) {
try {
synchronization.afterCompletion(status);
}
catch (Throwable tsex) {
logger.error("TransactionSynchronization.afterCompletion threw exception", tsex);
}
}
}
}
}
4.3 事务同步应用场景
java
@Component
public class TransactionSynchronizationExample {
// 会话同步:在事务提交后更新会话
@Component
public static class SessionSynchronization implements TransactionSynchronization {
private final String sessionId;
private final Object sessionData;
public SessionSynchronization(String sessionId, Object sessionData) {
this.sessionId = sessionId;
this.sessionData = sessionData;
}
@Override
public void afterCommit() {
// 事务成功提交后更新会话
SessionManager.updateSession(sessionId, sessionData);
}
@Override
public void afterCompletion(int status) {
// 无论事务成功还是失败,都清理资源
SessionManager.cleanupSession(sessionId);
}
}
// 缓存同步:在事务提交后更新缓存
@Component
public static class CacheSynchronization implements TransactionSynchronization {
private final String cacheKey;
private final Object cacheValue;
private final CacheOperation operation;
public CacheSynchronization(String cacheKey, Object cacheValue, CacheOperation operation) {
this.cacheKey = cacheKey;
this.cacheValue = cacheValue;
this.operation = operation;
}
@Override
public void afterCommit() {
// 事务成功提交后更新缓存
switch (operation) {
case PUT:
CacheManager.put(cacheKey, cacheValue);
break;
case EVICT:
CacheManager.evict(cacheKey);
break;
case CLEAR:
CacheManager.clear();
break;
}
}
@Override
public void afterCompletion(int status) {
// 如果事务失败,不更新缓存
if (status == STATUS_ROLLED_BACK) {
logger.debug("Transaction rolled back, skipping cache update for key: {}", cacheKey);
}
}
public enum CacheOperation {
PUT, EVICT, CLEAR
}
}
// 消息同步:在事务提交后发送消息
@Component
public static class MessageSynchronization implements TransactionSynchronization {
private final String topic;
private final Object message;
public MessageSynchronization(String topic, Object message) {
this.topic = topic;
this.message = message;
}
@Override
public void afterCommit() {
// 事务成功提交后发送消息
MessagePublisher.send(topic, message);
}
@Override
public void afterCompletion(int status) {
// 如果事务失败,记录日志
if (status == STATUS_ROLLED_BACK) {
logger.warn("Transaction rolled back, message not sent: {}", message);
}
}
}
// 使用事务同步
@Transactional
public void updateUserWithSync(User user) {
// 更新用户
userRepository.save(user);
// 注册会话同步
TransactionSynchronizationManager.registerSynchronization(
new SessionSynchronization(user.getSessionId(), user));
// 注册缓存同步
TransactionSynchronizationManager.registerSynchronization(
new CacheSynchronization("user:" + user.getId(), user, CacheSynchronization.CacheOperation.PUT));
// 注册消息同步
TransactionSynchronizationManager.registerSynchronization(
new MessageSynchronization("user.updated", user));
}
}
5. 事务提交与回滚机制
5.1 事务提交流程
Spring事务提交流程在AbstractPlatformTransactionManager.processCommit方法中实现:
java
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
boolean beforeCompletionInvoked = false;
try {
// 1. 提交前触发同步回调
triggerBeforeCommit(status);
// 2. 完成前触发同步回调
triggerBeforeCompletion(status);
beforeCompletionInvoked = true;
// 3. 根据是否有保存点进行不同处理
if (status.hasSavepoint()) {
// 嵌套事务:释放保存点
if (status.isDebug()) {
logger.debug("Releasing transaction savepoint");
}
status.releaseHeldSavepoint();
}
else if (status.isNewTransaction()) {
// 新事务:执行提交
if (status.isDebug()) {
logger.debug("Initiating transaction commit");
}
doCommit(status);
}
else if (isFailEarlyOnGlobalRollbackOnly()) {
// 参与现有事务:检查全局回滚标记
unexpectedRollback = status.isGlobalRollbackOnly();
}
}
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) {
// 触发完成回调并重新抛出
if (!beforeCompletionInvoked) {
triggerBeforeCompletion(status);
}
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
// 4. 触发提交后回调
try {
triggerAfterCommit(status);
}
finally {
// 5. 触发完成后回调
triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
}
}
finally {
// 6. 清理事务同步
cleanupAfterCompletion(status);
}
}
5.2 事务回滚流程
Spring事务回滚流程在AbstractPlatformTransactionManager.processRollback方法中实现:
java
private void processRollback(DefaultTransactionStatus status) {
try {
try {
// 1. 完成前触发同步回调
triggerBeforeCompletion(status);
// 2. 根据是否有保存点进行不同处理
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 if (status.hasTransaction()) {
// 参与现有事务:设置全局回滚标记
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
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 {
if (logger.isDebugEnabled()) {
logger.debug("No transaction available for rollback");
}
}
}
catch (RuntimeException | Error ex) {
// 触发完成回调并重新抛出
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
// 3. 触发完成后回调
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
}
finally {
// 4. 清理事务同步
cleanupAfterCompletion(status);
}
}
5.3 事务清理机制
事务清理在AbstractPlatformTransactionManager.cleanupAfterCompletion方法中实现:
java
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
// 1. 设置事务完成状态
status.setCompleted();
// 2. 如果是新事务同步,清除同步
if (status.isNewSynchronization()) {
TransactionSynchronizationManager.clear();
}
// 3. 如果是新事务,清理资源
if (status.isNewTransaction()) {
doCleanupAfterCompletion(status.getTransaction());
}
// 4. 如果有挂起资源,恢复
if (status.getSuspendedResources() != null) {
if (status.isDebug()) {
logger.debug("Resuming suspended transaction after completion of inner transaction");
}
resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
}
}
6. 事务异常处理机制
6.1 异常回滚规则
Spring事务默认情况下只对RuntimeException和Error进行回滚,对检查异常不回滚。这个规则在DefaultTransactionAttribute.rollbackOn方法中定义:
java
public class DefaultTransactionAttribute extends DefaultTransactionDefinition implements TransactionAttribute {
@Override
public boolean rollbackOn(Throwable ex) {
// 默认情况下,RuntimeException和Error会触发回滚
return (ex instanceof RuntimeException || ex instanceof Error);
}
}
可以通过@Transactional注解的rollbackFor和noRollbackFor属性自定义回滚规则:
java
public class RuleBasedTransactionAttribute extends DefaultTransactionAttribute {
private List<RollbackRuleAttribute> rollbackRules;
public RuleBasedTransactionAttribute(RollbackRuleAttribute... rollbackRules) {
this();
this.rollbackRules = Arrays.asList(rollbackRules);
}
@Override
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;
}
}
}
// 如果有匹配的回滚规则
if (winner == null) {
// 使用默认规则:RuntimeException和Error回滚
return logger.isDebugEnabled() ? !(ex instanceof BusinessException) : super.rollbackOn(ex);
}
// 根据规则判断是否回滚
return !(winner instanceof NoRollbackRuleAttribute);
}
}
// 回滚规则基类
public abstract class RollbackRuleAttribute implements Serializable {
private final Class<?> exceptionType;
public RollbackRuleAttribute(Class<?> exceptionType) {
Assert.notNull(exceptionType, "'exceptionType' cannot be null");
if (!Throwable.class.isAssignableFrom(exceptionType)) {
throw new IllegalArgumentException("'exceptionType' must be a Throwable type");
}
this.exceptionType = exceptionType;
}
public int getDepth(Throwable ex) {
return getDepth(ex.getClass(), 0);
}
private int getDepth(Class<?> exceptionClass, int depth) {
if (exceptionClass.getName().startsWith(this.exceptionType.getName())) {
return depth;
}
if (exceptionClass == Throwable.class) {
return -1;
}
return getDepth(exceptionClass.getSuperclass(), depth + 1);
}
public Class<?> getExceptionType() {
return this.exceptionType;
}
@Override
public String toString() {
return this.exceptionType.getName();
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof RollbackRuleAttribute)) {
return false;
}
RollbackRuleAttribute rhs = (RollbackRuleAttribute) other;
return this.exceptionType.equals(rhs.exceptionType);
}
@Override
public int hashCode() {
return this.exceptionType.hashCode();
}
}
// 回滚规则:指定异常需要回滚
public class RollbackRuleAttribute extends RollbackRuleAttribute {
public RollbackRuleAttribute(Class<?> exceptionType) {
super(exceptionType);
}
}
// 不回滚规则:指定异常不需要回滚
public class NoRollbackRuleAttribute extends RollbackRuleAttribute {
public NoRollbackRuleAttribute(Class<?> exceptionType) {
super(exceptionType);
}
}
6.2 异常处理流程
Spring事务异常处理流程在TransactionAspectSupport.completeTransactionAfterThrowing方法中实现:
java
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
// 1. 如果有事务属性
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
// 2. 判断是否需要回滚
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
// 3. 执行回滚
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 {
// 4. 不需要回滚,执行提交
try {
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;
}
}
}
}
7. 声明式事务注解解析
7.1 @Transactional注解属性
java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
// 事务管理器
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
// 传播行为
Propagation propagation() default Propagation.REQUIRED;
// 隔离级别
Isolation isolation() default Isolation.DEFAULT;
// 超时时间
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 只读事务
boolean readOnly() default false;
// 回滚异常
Class<? extends Throwable>[] rollbackFor() default {};
// 回滚异常名称
String[] rollbackForClassName() default {};
// 不回滚异常
Class<? extends Throwable>[] noRollbackFor() default {};
// 不回滚异常名称
String[] noRollbackForClassName() default {};
}
7.2 事务属性解析器
Spring事务属性解析器负责解析@Transactional注解并转换为TransactionAttribute对象:
java
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {
private final boolean publicMethodsOnly;
private final Set<TransactionAnnotationParser> annotationParsers;
private final boolean allowPublicMethodsOnly;
public AnnotationTransactionAttributeSource() {
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet<>(2);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
public AnnotationTransactionAttributeSource(Class<? extends Annotation>... annotationTypes) {
this.publicMethodsOnly = true;
this.annotationParsers = new LinkedHashSet<>(annotationTypes.length);
for (Class<? extends Annotation> annotationType : annotationTypes) {
this.annotationParsers.add(new SpringTransactionAnnotationParser(annotationType));
}
}
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
@Override
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
@Nullable
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
TransactionAttribute attr = parser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
}
// Spring事务注解解析器
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
private final Class<? extends Annotation> annotationType;
public SpringTransactionAnnotationParser() {
this.annotationType = Transactional.class;
}
public SpringTransactionAnnotationParser(Class<? extends Annotation> annotationType) {
this.annotationType = annotationType;
}
@Override
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, this.annotationType);
}
@Override
@Nullable
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
}
else {
return null;
}
}
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());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
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);
8. 编程式事务管理
8.1 TransactionTemplate实现
Spring提供了编程式事务管理的方式,主要通过TransactionTemplate和PlatformTransactionManager直接使用:
java
public class TransactionTemplate extends DefaultTransactionDefinition
implements TransactionOperations, InitializingBean {
private PlatformTransactionManager transactionManager;
public TransactionTemplate() {
}
public TransactionTemplate(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition definition) {
this.transactionManager = transactionManager;
setPropagationBehavior(definition.getPropagationBehavior());
setIsolationLevel(definition.getIsolationLevel());
setTimeout(definition.getTimeout());
setReadOnly(definition.isReadOnly());
setName(definition.getName());
}
@Override
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
}
@Override
@Nullable
public <T> T execute(TransactionCallback<T> action) throws TransactionException {
if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
}
else {
TransactionStatus status = this.transactionManager.getTransaction(this);
T result;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException | Error ex) {
// 事务回滚
rollbackOnException(status, ex);
throw ex;
}
catch (Throwable ex) {
// 事务回滚
rollbackOnException(status, ex);
throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
}
this.transactionManager.commit(status);
return result;
}
}
private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
try {
this.transactionManager.rollback(status);
}
catch (TransactionSystemException ex2) {
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
throw ex2;
}
catch (Throwable ex2) {
throw new UndeclaredThrowableException(ex2, "Application exception overridden by rollback exception");
}
}
}
// 事务回调接口
@FunctionalInterface
public interface TransactionCallback<T> {
@Nullable
T doInTransaction(TransactionStatus status);
}
// 不带返回值的事务回调接口
@FunctionalInterface
public interface TransactionCallbackWithoutResult extends TransactionCallback<Object> {
@Override
default Object doInTransaction(TransactionStatus status) {
doInTransactionWithoutResult(status);
return null;
}
void doInTransactionWithoutResult(TransactionStatus status);
}
8.2 编程式事务使用示例
java
@Service
public class ProgrammaticTransactionService {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private PlatformTransactionManager transactionManager;
public void updateUserWithTransactionTemplate(User user) {
// 使用TransactionTemplate
transactionTemplate.execute(status -> {
try {
userRepository.save(user);
// 其他业务操作
return null;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
});
}
public void updateUserWithTransactionManager(User user) {
// 直接使用PlatformTransactionManager
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
def.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
def.setTimeout(30);
TransactionStatus status = transactionManager.getTransaction(def);
try {
userRepository.save(user);
// 其他业务操作
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
public User findUserWithReadOnly(Long userId) {
// 只读事务
transactionTemplate.setReadOnly(true);
return transactionTemplate.execute(status -> {
return userRepository.findById(userId);
});
}
public void updateUserWithPropagation(User user) {
// 设置传播行为
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionTemplate.execute(status -> {
userRepository.save(user);
return null;
});
}
}
9. 事务与Spring生态集成
9.1 事务与JPA集成
Spring Data JPA与Spring事务的集成主要通过JpaTransactionManager实现:
java
public class JpaTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean {
@Nullable
private EntityManagerFactory entityManagerFactory;
@Nullable
private DataSource dataSource;
private JpaDialect jpaDialect;
private boolean lazyDatabaseTransaction = false;
public JpaTransactionManager() {
setNestedTransactionAllowed(true);
}
public JpaTransactionManager(EntityManagerFactory emf) {
this();
this.entityManagerFactory = emf;
afterPropertiesSet();
}
@Override
public void afterPropertiesSet() {
if (getEntityManagerFactory() == null) {
throw new IllegalArgumentException("'entityManagerFactory' or 'persistenceUnitName' is required");
}
if (this.jpaDialect == null) {
EntityManagerFactory emf = getEntityManagerFactory();
if (emf instanceof EntityManagerFactoryInfo) {
this.jpaDialect = ((EntityManagerFactoryInfo) emf).getJpaDialect();
}
else {
this.jpaDialect = new DefaultJpaDialect();
}
}
}
@Override
protected Object doGetTransaction() {
JpaTransactionObject txObject = new JpaTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.getResource(getEntityManagerFactory());
if (emHolder != null) {
txObject.setEntityManagerHolder(emHolder, false);
}
return txObject;
}
@Override
protected boolean isExistingTransaction(Object transaction) {
JpaTransactionObject txObject = (JpaTransactionObject) transaction;
return (txObject.hasEntityManagerHolder() && txObject.getEntityManagerHolder().isTransactionActive());
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
JpaTransactionObject txObject = (JpaTransactionObject) transaction;
if (txObject.getEntityManagerHolder() == null ||
txObject.getEntityManagerHolder().isSynchronizedWithTransaction()) {
EntityManager em = null;
try {
em = createEntityManagerForTransaction();
if (logger.isDebugEnabled()) {
logger.debug("Opened new EntityManager [" + em + "] for JPA transaction");
}
txObject.setEntityManagerHolder(new EntityManagerHolder(em), true);
}
catch (PersistenceException ex) {
throw new CannotCreateTransactionException("Could not open JPA EntityManager for transaction", ex);
}
}
EntityManager em = txObject.getEntityManagerHolder().getEntityManager();
try {
if (!definition.isReadOnly() && !txObject.getEntityManagerHolder().isSynchronizedWithTransaction()) {
Object transactionData = getJpaDialect().beginTransaction(em, definition);
txObject.setTransactionData(transactionData);
}
EntityManagerHolder emHolder = txObject.getEntityManagerHolder();
emHolder.setSynchronizedWithTransaction(true);
emHolder.setTransactionActive(true);
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
emHolder.setTimeoutInSeconds(timeout);
}
if (getDataSource() != null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
emHolder.setConnectionHolder(conHolder);
}
TransactionSynchronizationManager.bindResource(
getEntityManagerFactory(), txObject.getEntityManagerHolder());
}
catch (TransactionException ex) {
closeEntityManagerAfterFailedBegin(txObject);
throw ex;
}
catch (RuntimeException ex) {
closeEntityManagerAfterFailedBegin(txObject);
throw ex;
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Committing JPA transaction on EntityManager [" +
txObject.getEntityManagerHolder().getEntityManager() + "]");
}
try {
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction();
tx.commit();
}
catch (RuntimeException ex) {
if (getJpaDialect() != null) {
ex = getJpaDialect().translateExceptionIfPossible(ex);
}
throw new TransactionSystemException("Could not commit JPA transaction", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Rolling back JPA transaction on EntityManager [" +
txObject.getEntityManagerHolder().getEntityManager() + "]");
}
try {
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction();
if (tx.isActive()) {
tx.rollback();
}
}
catch (RuntimeException ex) {
if (getJpaDialect() != null) {
ex = getJpaDialect().translateExceptionIfPossible(ex);
}
throw new TransactionSystemException("Could not roll back JPA transaction", ex);
}
}
@Override
protected void doCleanupAfterCompletion(Object transaction) {
JpaTransactionObject txObject = (JpaTransactionObject) transaction;
// 清理资源
if (txObject.isNewEntityManagerHolder()) {
TransactionSynchronizationManager.unbindResource(getEntityManagerFactory());
}
EntityManager em = txObject.getEntityManagerHolder().getEntityManager();
if (txObject.isNewEntityManagerHolder()) {
EntityManagerFactoryUtils.closeEntityManager(em);
}
else {
try {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
}
catch (RuntimeException ex) {
logger.debug("Could not roll back JPA transaction after completion", ex);
}
}
txObject.getEntityManagerHolder().clear();
}
protected EntityManager createEntityManagerForTransaction() {
return EntityManagerFactoryUtils.doGetTransactionalEntityManager(
getEntityManagerFactory(), getJpaDialect(), isSynchronizedWithTransaction());
}
}
9.2 事务与MyBatis集成
Spring与MyBatis的事务集成主要通过DataSourceTransactionManager实现,因为MyBatis底层使用JDBC连接:
java
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {
@Bean
public DataSource dataSource() {
// 配置数据源
return new HikariDataSource();
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
return sessionFactory.getObject();
}
}
@Service
public class MyBatisUserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void updateUser(User user) {
// MyBatis操作会自动参与到Spring事务中
userMapper.updateUser(user);
userMapper.updateUserDetail(user.getDetail());
}
}
9.3 事务与Hibernate集成
Spring与Hibernate的事务集成通过HibernateTransactionManager实现:
java
public class HibernateTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, InitializingBean {
@Nullable
private SessionFactory sessionFactory;
@Nullable
private DataSource dataSource;
private boolean autodetectDataSource = true;
private boolean allowResultAccessAfterCompletion = false;
public HibernateTransactionManager() {
setNestedTransactionAllowed(true);
}
public HibernateTransactionManager(SessionFactory sessionFactory) {
this();
this.sessionFactory = sessionFactory;
afterPropertiesSet();
}
@Override
public void afterPropertiesSet() {
if (getSessionFactory() == null) {
throw new IllegalArgumentException("'sessionFactory' is required");
}
if (this.dataSource == null) {
if (this.autodetectDataSource && getSessionFactory() instanceof SessionFactoryImplementor) {
ServiceRegistry serviceRegistry = ((SessionFactoryImplementor) getSessionFactory()).getServiceRegistry();
ConnectionProvider connectionProvider = serviceRegistry.getService(ConnectionProvider.class);
if (connectionProvider instanceof DatasourceConnectionProviderImpl) {
this.dataSource = ((DatasourceConnectionProviderImpl) connectionProvider).getDataSource();
}
}
}
}
@Override
protected Object doGetTransaction() {
HibernateTransactionObject txObject = new HibernateTransactionObject();
txObject.setSavepointAllowed(isNestedTransactionAllowed());
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if (sessionHolder != null) {
if (logger.isDebugEnabled()) {
logger.debug("Found thread-bound Session [" +
sessionHolder.getSession() + "] for Hibernate transaction");
}
txObject.setSessionHolder(sessionHolder, false);
}
if (getDataSource() != null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
txObject.setConnectionHolder(conHolder);
}
return txObject;
}
@Override
protected boolean isExistingTransaction(Object transaction) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
return (txObject.hasSessionHolder() && txObject.getSessionHolder().isTransactionActive());
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.hasSessionHolder() && !txObject.getSessionHolder().isSynchronizedWithTransaction()) {
throw new IllegalTransactionStateException(
"Pre-bound JDBC Session found and HibernateTransactionManager does not support " +
"running within DataSourceTransactionManager: either set up HibernateTransactionManager " +
"explicitly or switch to DataSourceTransactionManager for JDBC-based JTA transactions");
}
Session session = null;
try {
if (!txObject.hasSessionHolder() || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Session newSession = obtainSessionFactory().openSession();
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
}
txObject.setSessionHolder(new SessionHolder(newSession), true);
}
SessionHolder sessionHolder = txObject.getSessionHolder();
sessionHolder.setSynchronizedWithTransaction(true);
sessionHolder.setTransactionActive(true);
session = sessionHolder.getSession();
if (this.autodetectDataSource && getDataSource() != null) {
Connection con = session.connection();
ConnectionHolder conHolder = new ConnectionHolder(con);
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC [" + con + "]");
}
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
txObject.setConnectionHolder(conHolder);
}
// 开始Hibernate事务
session.beginTransaction();
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
sessionHolder.setTimeoutInSeconds(timeout);
}
// 绑定会话持有者到同步管理器
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
}
}
catch (Throwable ex) {
if (txObject.isNewSessionHolder()) {
SessionFactoryUtils.releaseSession(session, getSessionFactory());
txObject.setSessionHolder(null, false);
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Committing Hibernate transaction on Session [" +
txObject.getSessionHolder().getSession() + "]");
}
try {
Transaction tx = txObject.getSessionHolder().getSession().getTransaction();
tx.commit();
}
catch (RuntimeException ex) {
if (isHibernateFlushFailure(ex)) {
throw convertHibernateAccessException(ex);
}
throw ex;
}
catch (Error err) {
throw err;
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Rolling back Hibernate transaction on Session [" +
txObject.getSessionHolder().getSession() + "]");
}
try {
Transaction tx = txObject.getSessionHolder().getSession().getTransaction();
if (tx.isActive()) {
tx.rollback();
}
}
catch (RuntimeException ex) {
throw convertHibernateAccessException(ex);
}
catch (Error err) {
throw err;
}
}
@Override
protected void doCleanupAfterCompletion(Object transaction) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
// 清理资源
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.unbindResource(getSessionFactory());
}
if (getDataSource() != null && txObject.hasConnectionHolder()) {
TransactionSynchronizationManager.unbindResource(getDataSource());
}
Session session = txObject.getSessionHolder().getSession();
if (txObject.isNewSessionHolder()) {
SessionFactoryUtils.releaseSession(session, getSessionFactory());
}
else {
try {
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
}
catch (HibernateException ex) {
logger.debug("Could not roll back Hibernate Session after completion", ex);
}
finally {
closeSessionAfterCompletion(session);
}
}
txObject.getSessionHolder().clear();
}
protected boolean isHibernateFlushFailure(RuntimeException ex) {
return (ex instanceof QueryException || ex instanceof ConstraintViolationException);
}
protected RuntimeException convertHibernateAccessException(RuntimeException ex) {
return SessionFactoryUtils.convertHibernateAccessException(ex);
}
protected void closeSessionAfterCompletion(Session session) {
try {
SessionFactoryUtils.closeSession(session);
}
catch (RuntimeException ex) {
logger.debug("Could not close Hibernate Session after completion", ex);
}
}
}
10. 分布式事务实现
10.1 JTA事务管理
Java Transaction API (JTA) 是Java EE标准中用于分布式事务管理的API,Spring通过JtaTransactionManager支持JTA事务:
java
public class JtaTransactionManager extends AbstractPlatformTransactionManager implements TransactionManager, InitializingBean {
@Nullable
private UserTransaction userTransaction;
@Nullable
private TransactionManager transactionManager;
private boolean allowCustomIsolationLevels = false;
private boolean autodetectUserTransaction = true;
private boolean cacheUserTransaction = true;
private boolean autodetectTransactionManager = true;
private boolean cacheTransactionManager = true;
public JtaTransactionManager() {
setNestedTransactionAllowed(false);
}
public JtaTransactionManager(UserTransaction userTransaction) {
this();
this.userTransaction = userTransaction;
}
public JtaTransactionManager(TransactionManager transactionManager) {
this();
this.transactionManager = transactionManager;
}
public JtaTransactionManager(UserTransaction userTransaction, TransactionManager transactionManager) {
this();
this.userTransaction = userTransaction;
this.transactionManager = transactionManager;
}
@Override
public void afterPropertiesSet() throws TransactionSystemException {
if (getUserTransaction() == null && this.autodetectUserTransaction) {
setUserTransaction lookupUserTransaction());
}
if (getTransactionManager() == null && this.autodetectTransactionManager) {
setTransactionManager(lookupTransactionManager());
}
checkUserTransactionAndTransactionManager();
}
@Override
protected Object doGetTransaction() {
JtaTransactionObject txObject = new JtaTransactionObject();
txObject.setSavepointAllowed(false);
return txObject;
}
@Override
protected boolean isExistingTransaction(Object transaction) throws TransactionSystemException {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
return (txObject.getUserTransaction().getStatus() != Status.STATUS_NO_TRANSACTION);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on getStatus", ex);
}
}
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
try {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
throw new InvalidIsolationLevelException("JTA does not support custom isolation levels");
}
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
txObject.getUserTransaction().setTransactionTimeout(timeout);
}
txObject.getUserTransaction().begin();
if (logger.isDebugEnabled()) {
logger.debug("Began JTA transaction");
}
}
catch (NotSupportedException ex) {
throw new CannotCreateTransactionException("JTA implementation does not support nested transactions", ex);
}
catch (UnsupportedOperationException ex) {
throw new IllegalTransactionStateException("JTA implementation does not support nested transactions", ex);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on begin", ex);
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
if (status.isDebug()) {
logger.debug("Committing JTA transaction");
}
txObject.getUserTransaction().commit();
}
catch (RollbackException ex) {
throw new UnexpectedRollbackException("JTA transaction rolled back", ex);
}
catch (HeuristicMixedException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_MIXED, ex);
}
catch (HeuristicRollbackException ex) {
throw new HeuristicCompletionException(HeuristicCompletionException.STATE_ROLLED_BACK, ex);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on commit", ex);
}
}
@Override
protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
try {
if (status.isDebug()) {
logger.debug("Rolling back JTA transaction");
}
txObject.getUserTransaction().rollback();
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on rollback", ex);
}
}
@Override
protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException {
JtaTransactionObject txObject = (JtaTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Setting JTA transaction rollback-only");
}
try {
txObject.getUserTransaction().setRollbackOnly();
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on setRollbackOnly", ex);
}
}
@Override
protected void doCleanupAfterCompletion(Object transaction) {
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
if (logger.isDebugEnabled()) {
logger.debug("Clearing JTA transaction");
}
// 清理资源
txObject.reset();
}
protected UserTransaction lookupUserTransaction() throws TransactionSystemException {
try {
UserTransaction ut = JndiTemplate.getDefaultInstance().lookup("java:comp/UserTransaction", UserTransaction.class);
if (logger.isDebugEnabled()) {
logger.debug("JTA UserTransaction found at default JNDI location [java:comp/UserTransaction]");
}
return ut;
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA UserTransaction is not available at JNDI location [java:comp/UserTransaction]", ex);
}
}
protected TransactionManager lookupTransactionManager() throws TransactionSystemException {
try {
TransactionManager tm = JndiTemplate.getDefaultInstance().lookup("java:comp/TransactionManager", TransactionManager.class);
if (logger.isDebugEnabled()) {
logger.debug("JTA TransactionManager found at default JNDI location [java:comp/TransactionManager]");
}
return tm;
}
catch (NamingException ex) {
throw new TransactionSystemException(
"JTA TransactionManager is not available at JNDI location [java:comp/TransactionManager]", ex);
}
}
private void checkUserTransactionAndTransactionManager() throws IllegalStateException {
if (this.userTransaction == null) {
throw new IllegalArgumentException("'userTransaction' or 'userTransactionName' is required");
}
}
protected static class JtaTransactionObject implements SmartTransactionObject {
@Nullable
private UserTransaction userTransaction;
@Nullable
private TransactionManager transactionManager;
public void setUserTransaction(@Nullable UserTransaction userTransaction) {
this.userTransaction = userTransaction;
}
public UserTransaction getUserTransaction() {
if (this.userTransaction == null) {
throw new IllegalStateException("No JTA UserTransaction available");
}
return this.userTransaction;
}
public void setTransactionManager(@Nullable TransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionManager getTransactionManager() {
return this.transactionManager;
}
public boolean isRollbackOnly() {
try {
return (getUserTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK);
}
catch (SystemException ex) {
throw new TransactionSystemException("JTA failure on getStatus", ex);
}
}
public void reset() {
// 清理资源
}
}
}
10.2 多数据源事务管理
在实际应用中,经常需要跨多个数据源进行事务管理,Spring提供了多种解决方案:
方案1:使用JTA事务管理器
java
@Configuration
public class JtaTransactionConfig {
@Bean(name = "dataSourceA")
public DataSource dataSourceA() {
return new HikariDataSource();
}
@Bean(name = "dataSourceB")
public DataSource dataSourceB() {
return new HikariDataSource();
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JtaTransactionManager();
}
}
@Service
public class MultiDataSourceService {
@Autowired
private JdbcTemplate jdbcTemplateA;
@Autowired
private JdbcTemplate jdbcTemplateB;
@Transactional
public void transferMoney(String fromAccount, String toAccount, BigDecimal amount) {
// 从数据源A扣款
jdbcTemplateA.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromAccount);
// 向数据源B存款
jdbcTemplateB.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toAccount);
// 如果发生异常,两个操作都会回滚
}
}
方案2:使用编程式事务管理多个数据源
java
@Service
public class MultiDataSourceProgrammaticService {
@Autowired
private PlatformTransactionManager transactionManagerA;
@Autowired
private PlatformTransactionManager transactionManagerB;
public void transferMoney(String fromAccount, String toAccount, BigDecimal amount) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus statusA = transactionManagerA.getTransaction(def);
TransactionStatus statusB = transactionManagerB.getTransaction(def);
try {
// 从数据源A扣款
jdbcTemplateA.update("UPDATE account SET balance = balance - ? WHERE id = ?", amount, fromAccount);
// 向数据源B存款
jdbcTemplateB.update("UPDATE account SET balance = balance + ? WHERE id = ?", amount, toAccount);
// 提交两个事务
transactionManagerA.commit(statusA);
transactionManagerB.commit(statusB);
} catch (Exception e) {
// 回滚两个事务
transactionManagerA.rollback(statusA);
transactionManagerB.rollback(statusB);
throw e;
}
}
}
11. 事务性能优化与监控
11.1 事务性能优化策略
11.1.1 优化事务边界
java
@Service
public class OptimizedTransactionService {
// 不好的实践:事务范围过大
@Transactional
public void badPractice(Long userId) {
// 查询操作(不需要事务)
User user = userRepository.findById(userId);
// 远程调用(不应该在事务中)
ExternalData data = externalService.getData(user.getId());
// 业务计算(不需要事务)
BigDecimal result = calculateResult(user, data);
// 只有这里需要事务
userRepository.updateUserResult(userId, result);
}
// 好的实践:事务范围最小化
public void goodPractice(Long userId) {
// 查询操作(不需要事务)
User user = userRepository.findById(userId);
// 远程调用(不应该在事务中)
ExternalData data = externalService.getData(user.getId());
// 业务计算(不需要事务)
BigDecimal result = calculateResult(user, data);
// 只有这里需要事务
updateUserResult(userId, result);
}
@Transactional
public void updateUserResult(Long userId, BigDecimal result) {
userRepository.updateUserResult(userId, result);
}
}
11.1.2 使用只读事务
java
@Service
public class ReadOnlyTransactionService {
// 只读事务:数据库可以进行优化
@Transactional(readOnly = true)
public List<User> findActiveUsers() {
return userRepository.findByStatus("ACTIVE");
}
// 复杂查询:使用只读事务
@Transactional(readOnly = true, timeout = 60)
public UserStatistics generateUserStatistics() {
// 复杂的统计查询
return userRepository.generateStatistics();
}
}
11.1.3 设置合适的隔离级别
java
@Service
public class IsolationLevelService {
// 读已提交:适合大多数场景
@Transactional(isolation = Isolation.READ_COMMITTED)
public void updateUser(User user) {
userRepository.save(user);
}
// 可重复读:适合需要一致性读取的场景
@Transactional(isolation = Isolation.REPEATABLE_READ)
public User getUserWithConsistentRead(Long userId) {
User user = userRepository.findById(userId);
// 在同一事务中多次读取,保证数据一致性
List<Order> orders = orderRepository.findByUserId(userId);
user.setOrders(orders);
return user;
}
// 串行化:适合高并发写入场景
@Transactional(isolation = Isolation.SERIALIZABLE)
public void transferMoney(String fromAccount, String toAccount, BigDecimal amount) {
accountRepository.debit(fromAccount, amount);
accountRepository.credit(toAccount, amount);
}
}
11.1.4 设置合适的超时时间
java
@Service
public class TimeoutTransactionService {
// 短事务:设置较短的超时时间
@Transactional(timeout = 5)
public void quickUpdate(User user) {
userRepository.save(user);
}
// 长事务:设置较长的超时时间
@Transactional(timeout = 60)
public void batchUpdate(List<User> users) {
for (User user : users) {
userRepository.save(user);
}
}
}
11.2 事务监控与调试
11.2.1 事务监控AOP
java
@Aspect
@Component
public class TransactionMonitorAspect {
private static final Logger logger = LoggerFactory.getLogger(TransactionMonitorAspect.class);
@Autowired
private MeterRegistry meterRegistry;
@Around("@annotation(transactional)")
public Object monitorTransaction(ProceedingJoinPoint joinPoint, Transactional transactional) throws Throwable {
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
String transactionName = className + "." + methodName;
long startTime = System.currentTimeMillis();
Timer.Sample sample = Timer.start(meterRegistry);
try {
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - startTime;
sample.stop(Timer.builder("transaction.duration")
.tag("method", transactionName)
.tag("status", "success")
.register(meterRegistry));
logger.info("Transaction executed successfully: {}.{} took {} ms",
className, methodName, duration);
return result;
}
catch (Exception e) {
long duration = System.currentTimeMillis() - startTime;
sample.stop(Timer.builder("transaction.duration")
.tag("method", transactionName)
.tag("status", "failure")
.register(meterRegistry));
meterRegistry.counter("transaction.failure",
"method", transactionName,
"exception", e.getClass().getSimpleName())
.increment();
logger.error("Transaction failed: {}.{} took {} ms",
className, methodName, duration, e);
throw e;
}
}
}
11.2.2 事务日志记录
java
@Component
public class TransactionLogger {
private static final Logger logger = LoggerFactory.getLogger(TransactionLogger.class);
@EventListener
public void handleTransactionStarted(TransactionStartedEvent event) {
logger.info("Transaction started: {}", event.getTransactionName());
}
@EventListener
public void handleTransactionCommitted(TransactionCommittedEvent event) {
logger.info("Transaction committed: {}", event.getTransactionName());
}
@EventListener
public void handleTransactionRolledBack(TransactionRolledBackEvent event) {
logger.warn("Transaction rolled back: {}", event.getTransactionName());
}
}
// 事务事件发布器
@Component
public class TransactionEventPublisher {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void publishTransactionStarted(String transactionName) {
eventPublisher.publishEvent(new TransactionStartedEvent(transactionName));
}
public void publishTransactionCommitted(String transactionName) {
eventPublisher.publishEvent(new TransactionCommittedEvent(transactionName));
}
public void publishTransactionRolledBack(String transactionName) {
eventPublisher.publishEvent(new TransactionRolledBackEvent(transactionName));
}
}
11.2.3 事务同步监控
java
@Component
public class TransactionSyncMonitor implements TransactionSynchronization {
private static final Logger logger = LoggerFactory.getLogger(TransactionSyncMonitor.class);
private final String transactionName;
private final long startTime;
public TransactionSyncMonitor(String transactionName) {
this.transactionName = transactionName;
this.startTime = System.currentTimeMillis();
}
@Override
public void beforeCommit(boolean readOnly) {
logger.info("Transaction {} is about to commit, readOnly: {}", transactionName, readOnly);
}
@Override
public void afterCommit() {
long duration = System.currentTimeMillis() - startTime;
logger.info("Transaction {} committed successfully in {} ms", transactionName, duration);
}
@Override
public void beforeCompletion() {
logger.debug("Transaction {} is about to complete", transactionName);
}
@Override
public void afterCompletion(int status) {
long duration = System.currentTimeMillis() - startTime;
if (status == STATUS_ROLLED_BACK) {
logger.warn("Transaction {} rolled back in {} ms", transactionName, duration);
} else if (status == STATUS_COMMITTED) {
logger.info("Transaction {} completed successfully in {} ms", transactionName, duration);
} else {
logger.warn("Transaction {} completed with unknown status in {} ms", transactionName, duration);
}
}
}
// 注册事务同步监控
@Aspect
@Component
public class TransactionSyncMonitorAspect {
@Autowired
private ApplicationContext applicationContext;
@Around("@annotation(transactional)")
public Object monitorTransactionSync(ProceedingJoinPoint joinPoint, Transactional transactional) throws Throwable {
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getSimpleName();
String transactionName = className + "." + methodName;
// 注册事务同步监控
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(
new TransactionSyncMonitor(transactionName));
}
return joinPoint.proceed();
}
}
12. 常见问题与解决方案
12.1 事务失效场景与解决方案
12.1.1 方法内部调用导致事务失效
java
@Service
public class InternalCallService {
// 问题:内部调用不会触发事务
public void methodA() {
// 这种调用不会触发事务
this.methodB();
}
@Transactional
public void methodB() {
// 事务不会生效
}
// 解决方案1:通过AopContext获取代理对象
public void methodAFixed() {
((InternalCallService) AopContext.currentProxy()).methodB();
}
// 解决方案2:注入自身
@Autowired
private InternalCallService self;
public void methodAFixed2() {
self.methodB();
}
// 解决方案3:将事务方法移到另一个Service
@Autowired
private TransactionalService transactionalService;
public void methodAFixed3() {
transactionalService.methodB();
}
}
@Service
public class TransactionalService {
@Transactional
public void methodB() {
// 事务会生效
}
}
12.1.2 private方法导致事务失效
java
@Service
public class PrivateMethodService {
// 问题:private方法事务不会生效
@Transactional
private void privateMethod() {
// 事务不会生效
}
// 解决方案:改为public方法
@Transactional
public void publicMethod() {
// 事务会生效
}
// 如果必须保持private,可以通过public方法调用
@Transactional
public void wrapperMethod() {
privateMethod();
}
private void privateMethod() {
// 通过wrapperMethod调用,事务会生效
}
}
12.1.3 异常被捕获导致事务不回滚
java
@Service
public class ExceptionHandlingService {
// 问题:异常被捕获,事务不会回滚
@Transactional
public void methodWithCaughtException() {
try {
// 业务逻辑
throw new RuntimeException("测试异常");
}
catch (Exception e) {
// 异常被捕获,事务不会回滚
logger.error("发生异常", e);
}
}
// 解决方案1:重新抛出异常
@Transactional
public void methodWithRethrownException() {
try {
// 业务逻辑
throw new RuntimeException("测试异常");
}
catch (Exception e) {
logger.error("发生异常", e);
// 重新抛出异常
throw e;
}
}
// 解决方案2:手动设置回滚
@Transactional
public void methodWithManualRollback() {
try {
// 业务逻辑
throw new RuntimeException("测试异常");
}
catch (Exception e) {
logger.error("发生异常", e);
// 手动设置回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
// 解决方案3:指定回滚异常
@Transactional(rollbackFor = Exception.class)
public void methodWithSpecifiedRollback() {
try {
// 业务逻辑
throw new Exception("测试异常");
}
catch (Exception e) {
logger.error("发生异常", e);
// 即使是检查异常,也会回滚
throw e;
}
}
}
12.2 事务传播行为问题
12.2.1 嵌套事务回滚问题
java
@Service
public class NestedTransactionService {
// 问题:嵌套事务回滚会影响外部事务
@Transactional
public void outerMethod() {
try {
// 外部事务操作
userRepository.save(new User("外部用户"));
// 调用内部方法
innerMethod();
} catch (Exception e) {
logger.error("内部方法失败", e);
}
}
@Transactional(propagation = Propagation.REQUIRED)
public void innerMethod() {
// 内部事务操作
userRepository.save(new User("内部用户"));
throw new RuntimeException("内部方法异常");
}
// 解决方案:使用嵌套事务
@Transactional
public void outerMethodFixed() {
try {
// 外部事务操作
userRepository.save(new User("外部用户"));
// 调用内部方法
innerMethodFixed();
} catch (Exception e) {
logger.error("内部方法失败", e);
}
// 外部事务会成功提交
}
@Transactional(propagation = Propagation.NESTED)
public void innerMethodFixed() {
// 内部事务操作
userRepository.save(new User("内部用户"));
throw new RuntimeException("内部方法异常");
// 只有内部操作会回滚,外部操作不会受影响
}
}
12.2.2 新事务传播问题
java
@Service
public class RequiresNewTransactionService {
// 问题:新事务中的异常不会影响外部事务
@Transactional
public void outerMethod() {
try {
// 外部事务操作
userRepository.save(new User("外部用户"));
// 调用内部方法
innerMethod();
} catch (Exception e) {
logger.error("内部方法失败", e);
// 外部事务仍然会提交
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void innerMethod() {
// 内部事务操作
userRepository.save(new User("内部用户"));
throw new RuntimeException("内部方法异常");
// 内部事务会回滚,但不会影响外部事务
}
// 解决方案:检查内部方法执行结果
@Transactional
public void outerMethodFixed() {
// 外部事务操作
userRepository.save(new User("外部用户"));
try {
// 调用内部方法
innerMethod();
} catch (Exception e) {
logger.error("内部方法失败", e);
// 根据业务需要决定是否回滚外部事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
}
12.3 事务与并发问题
12.3.1 乐观锁实现
java
@Entity
public class Product {
@Id
private Long id;
private String name;
private Integer stock;
@Version
private Long version;
// getters and setters
}
@Service
public class OptimisticLockService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductStock(Long productId, Integer quantity) {
Product product = productRepository.findById(productId);
// 检查库存
if (product.getStock() < quantity) {
throw new InsufficientStockException("库存不足");
}
// 更新库存
product.setStock(product.getStock() - quantity);
productRepository.save(product);
// 如果版本号不匹配,会抛出OptimisticLockingFailureException
}
@Transactional
public void updateProductStockWithRetry(Long productId, Integer quantity) {
int maxRetries = 3;
int retryCount = 0;
while (retryCount < maxRetries) {
try {
updateProductStock(productId, quantity);
return;
} catch (OptimisticLockingFailureException e) {
retryCount++;
if (retryCount >= maxRetries) {
throw new ConcurrencyException("并发更新失败,请重试");
}
// 短暂等待后重试
try {
Thread.sleep(50);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("线程被中断", ie);
}
}
}
}
}
12.3.2 悲观锁实现
java
@Service
public class PessimisticLockService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductStockWithPessimisticLock(Long productId, Integer quantity) {
// 使用悲观锁获取产品
Product product = productRepository.findByIdWithLock(productId);
// 检查库存
if (product.getStock() < quantity) {
throw new InsufficientStockException("库存不足");
}
// 更新库存
product.setStock(product.getStock() - quantity);
productRepository.save(product);
}
}
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT p FROM Product p WHERE p.id = :id")
Product findByIdWithLock(@Param("id") Long id);
}
13. 总结
Spring事务管理是企业级应用开发中的核心功能,它通过AOP代理、事务管理器、同步机制等组件提供了强大而灵活的事务管理能力。本文从源码层面深入分析了Spring事务的实现机制,特别是事务传播机制的实现原理。
13.1 核心要点回顾
-
事务管理器架构 :Spring提供了多种事务管理器实现,如
DataSourceTransactionManager、JpaTransactionManager、HibernateTransactionManager等,它们都继承自AbstractPlatformTransactionManager,实现了通用的事务管理逻辑。 -
AOP代理机制 :Spring通过
InfrastructureAdvisorAutoProxyCreator自动创建事务代理,使用TransactionInterceptor拦截方法调用,在方法执行前后添加事务逻辑。 -
事务传播行为 :Spring定义了7种事务传播行为,通过
handleExistingTransaction方法实现,每种传播行为都有其特定的应用场景和实现方式。 -
事务同步机制 :
TransactionSynchronizationManager是Spring事务同步的核心管理器,负责管理事务资源和同步回调,通过线程本地变量实现事务上下文的传递。 -
事务提交与回滚 :Spring事务提交流程在
processCommit方法中实现,回滚流程在processRollback方法中实现,两者都会触发相应的同步回调。 -
异常处理机制 :Spring事务默认只对
RuntimeException和Error进行回滚,可以通过@Transactional注解的rollbackFor和noRollbackFor属性自定义回滚规则。
13.2 最佳实践建议
-
合理设置事务边界:事务范围应该尽可能小,只包含需要原子性保证的操作,避免在事务中进行远程调用、文件操作等耗时操作。
-
选择合适的隔离级别:根据业务需求选择合适的隔离级别,平衡数据一致性和并发性能。
-
正确使用事务传播行为:理解各种传播行为的含义和应用场景,避免因误用导致的事务问题。
-
处理异常情况:正确处理异常,确保事务能够正确回滚或提交,避免因异常处理不当导致的数据不一致。
-
监控事务性能:通过AOP和事务同步机制监控事务执行情况,及时发现和解决性能问题。