Spring事务探索

Spring Transaction

在Spring事务管理SPI(Service Provider Interface)的抽象层主要包括3个接口,分别是PlatformTransactionManager、TransactionDefinition和TransactionStatus。如下图所示:
事务接口拓扑图
PlatformTransactionManager 定义了事务的流程, getTransaction, commit, rollback 三个方法。
getTransaction 返回事务状态对象, commit 提交事务, rollback 回滚事务。

public interface PlatformTransactionManager {

    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;
}

TransactionDefinition 主要用于定义事务,包含事务的传播机制,隔离级别,超时时间,是否只读,事务名称等属性。同时定义了 7 个 PROPAGATION 级别, 5 个 ISOLATION 的常量。

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 = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;

int TIMEOUT_DEFAULT = -1;

TransactionStatus 主要用于获取事务的状态,继承自 SavepointManager 接口,该接口定义了保存点事务的特性,可以指定回滚到之前的保存点,而不是回滚整个事务。

public interface TransactionStatus extends SavepointManager {

    boolean isNewTransaction();

    boolean hasSavepoint();

    void setRollbackOnly();

    boolean isRollbackOnly();

    void flush();

    boolean isCompleted();

}

该流程主要由 PlatformTransactionManager 控制,它负责了事务的创建,提交,以及回滚。它使用 TransactionDefinition 来创建 TransactionStatus 对象,进而控制整个事务流程。实现有

DataSourceTransactionManager -> JDBC
HibernateTransactionManager -> Hibernate
JtaTransactionManager -> Jta
JpaTransactionManager -> Jpa 等等

初始化

让我们从 Spring 初始化开始一步一步解开 Spring 声明式事务的神秘面纱。
@EnableTransactionManagement是 Spring 事务的起点。看下这个注解的定义

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
	boolean proxyTargetClass() default false;
	AdviceMode mode() default AdviceMode.PROXY;
	int order() default Ordered.LOWEST_PRECEDENCE;
}

注解中有两个东西很重要,一个是TransactionManagementConfigurationSelector.class,另一个是AdviceMode.PROXYTransactionManagementConfigurationSelector.class是整个事务配置的具体配置方式,而AdviceMode.PROXY决定了我们使用Spring的具体实现方式。我们看下TransactionManagementConfigurationSelector类的具体实现:

protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {
						TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}

AdviceMode.PROXY对应的具体实现是AutoProxyRegistrar,ProxyTransactionManagementConfigurationAutoProxyRegistrar我们先忽略,这个是SpringAop相关的,我们重点关注ProxyTransactionManagementConfiguration, 核心代码如下:

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		advisor.setAdvice(transactionInterceptor());
		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对象,该对象是核心,他持有了TransactionAttributeSource, TransactionInterceptor对象。同时还包含了

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};

对象,这个对象会匹配所有的方法,同时通过TransactionAttributeSource来获取方法或类上的@Transactional注解

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

	@Override
	public boolean matches(Method method, Class<?> targetClass) {
		if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
			return false;
		}
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
	...
}

TransactionAttributeSource定义如下,具体的实现的抽象类AbstractFallbackTransactionAttributeSource

public interface TransactionAttributeSource {

	/**
	 * Return the transaction attribute for the given method,
	 * or {@code null} if the method is non-transactional.
	 * @param method the method to introspect
	 * @param targetClass the target class. May be {@code null},
	 * in which case the declaring class of the method must be used.
	 * @return TransactionAttribute the matching transaction attribute,
	 * or {@code null} if none found
	 */
	TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass);

}

AbstractFallbackTransactionAttributeSource实现了核心的流程,同时缓存所有解析过注解的方法,具体的注解解析由AnnotationTransactionAttributeSource实现,该类依赖TransactionAnnotationParser接口来解析。

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		if (element.getAnnotations().length > 0) {
			for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
				TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
				if (attr != null) {
					return attr;
				}
			}
		}
		return null;
	}

TransactionAnnotationParser接口定义如下:

public interface TransactionAnnotationParser {

	/**
	 * Parse the transaction attribute for the given method or class,
	 * based on an annotation type understood by this parser.
	 * <p>This essentially parses a known transaction annotation into Spring's metadata
	 * attribute class. Returns {@code null} if the method/class is not transactional.
	 * @param element the annotated method or class
	 * @return the configured transaction attribute, or {@code null} if none found
	 * @see AnnotationTransactionAttributeSource#determineTransactionAttribute
	 */
	TransactionAttribute parseTransactionAnnotation(AnnotatedElement element);
}

具体的实现类SpringTransactionAnnotationParser,它完成了解析注解的功能,并返回注解定义的接口TransactionAttribute,该接口继承自TransactionDefinition,具体逻辑如下:

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<RollbackRuleAttribute>();
		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);

		retrn rbta;
	}

到此,在初始化过程中,带有 @Transactional的方法或类对已经被Spring代理。

真实事务

切面代理已经完成,接下来就是方法调用过程中,真实事务的使用了。由上述提到的另外一个类完成。它就是TransactionInterceptor类。

Spring 事务由ReflectiveMethodInvocation代理类的proceed进入到TransactionInterceptorinvoke方法。该方法的实现如下:

@Override
	public Object invoke(final MethodInvocation invocation) throws Throwable {
		// Work out the target class: may be {@code null}.
		// The TransactionAttributeSource should be passed the target class
		// as well as the method, which may be from an interface.
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
			@Override
			public Object proceedWithInvocation() throws Throwable {
				return invocation.proceed();
			}
		});
	}

整个事务的核心实现就在invokeWithinTransaction方法中,

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}
		...
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass)

这个方法从初始化的缓存中获取方法或类上的事务定义TransactionAttribute

final PlatformTransactionManager tm = determineTransactionManager(txAttr);

这个方法获取事务的核心管理PlatformTransactionManager,具体实现如下:

protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
		// Do not attempt to lookup tx manager if no tx attributes are set
		if (txAttr == null || this.beanFactory == null) {
			return getTransactionManager();
		}
		String qualifier = txAttr.getQualifier();
		if (StringUtils.hasText(qualifier)) {
			return determineQualifiedTransactionManager(qualifier);
		}
		else if (StringUtils.hasText(this.transactionManagerBeanName)) {
			return determineQualifiedTransactionManager(this.transactionManagerBeanName);
		}
		else {
			PlatformTransactionManager defaultTransactionManager = getTransactionManager();
			if (defaultTransactionManager == null) {
				defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
				if (defaultTransactionManager == null) {
					defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
					this.transactionManagerCache.putIfAbsent(
							DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
				}
			}
			return defaultTransactionManager;
		}
	}

默认获取到的是 JDBC 的事务管理器DataSourceTransactionManager impl PlatformTransactionManager,JPA会获取到JpaTransactionManager
因此会进入到上述方法的if逻辑中,即会调用createTransactionIfNecessary方法,该方法会创建事务,并处理事务。核心实现如下:

protected TransactionInfo createTransactionIfNecessary(
			PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {

		// If no name specified, apply method identification as transaction name.
		if (txAttr != null && txAttr.getName() == null) {
			txAttr = new DelegatingTransactionAttribute(txAttr) {
				@Override
				public String getName() {
					return joinpointIdentification;
				}
			};
		}
		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}

事务的创建都在getTransaction方法中,我们下面会详细查看该方法。

prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);绑定事务信息到线程中

retVal = invocation.proceedWithInvocation();该方法是调用目标对象的方法,即我们自己的方法

completeTransactionAfterThrowing(txInfo, ex);处理事务异常情况,核心实现如下:

if (txInfo != null && txInfo.hasTransaction()) {
			if (txInfo.transactionAttribute.rollbackOn(ex)) {
				try {
					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
				...
				}
			}
			else {
				// We don't roll back on this exception.
				// Will still roll back if TransactionStatus.isRollbackOnly() is true.
				try {
					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
				}
				catch (TransactionSystemException ex2) {
				...
				}
		}

rollback方法具体实现都在AbstractPlatformTransactionManager类中

cleanupTransactionInfo(txInfo);清空线程绑定的事务信息

commitTransactionAfterReturning(txInfo);正常流程提交事务,核心实现如下:

if (txInfo != null && txInfo.hasTransaction()) {
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}

commit方法具体实现都在AbstractPlatformTransactionManager类中

AbstractPlatformTransactionManager

看下 Spring 的这个核心类实现,依次从 getTransaction, commit, rollback三个方法查看。

public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
		Object transaction = doGetTransaction();

		// Cache debug flag to avoid repeated checks.
		boolean debugEnabled = logger.isDebugEnabled();

		if (definition == null) {
			// Use defaults if no transaction definition given.
			definition = new DefaultTransactionDefinition();
		}

		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			return handleExistingTransaction(definition, transaction, debugEnabled);
		}

		// Check definition settings for new transaction.
		if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
		}

		// No existing transaction found -> check propagation behavior to find out how to proceed.
		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(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException ex) {
				resume(null, suspendedResources);
				throw ex;
			}
			catch (Error err) {
				resume(null, suspendedResources);
				throw err;
			}
		}
		else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
				logger.warn("Custom isolation level specified but no actual transaction initiated; " +
						"isolation level will effectively be ignored: " + definition);
			}
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
		}
	}
内容概要:论文提出了一种基于空间调制的能量高效分子通信方案(SM-MC),将传输符号分为空间符号和浓度符号。空间符号通过激活单个发射纳米机器人的索引来传输信息,浓度符号则采用传统的浓度移位键控(CSK)调制。相比现有的MIMO分子通信方案,SM-MC避免了链路间干扰,降低了检测复杂度并提高了性能。论文分析了SM-MC及其特例SSK-MC的符号错误率(SER),并通过仿真验证了其性能优于传统的MIMO-MC和SISO-MC方案。此外,论文还探讨了分子通信领域的挑战、优势及相关研究工作,强调了空间维度作为新的信息自由度的重要性,并提出了未来的研究方向和技术挑战。 适合人群:具备一定通信理论基础,特别是对纳米通信和分子通信感兴趣的科研人员、研究生和工程师。 使用场景及目标:①理解分子通信中空间调制的工作原理及其优势;②掌握SM-MC系统的具体实现细节,包括发射、接收、检测算法及性能分析;③对比不同分子通信方案(如MIMO-MC、SISO-MC、SSK-MC)的性能差异;④探索分子通信在纳米网络中的应用前景。 其他说明:论文不仅提供了详细的理论分析和仿真验证,还给出了具体的代码实现,帮助读者更好地理解和复现实验结果。此外,论文还讨论了分子通信领域的标准化进展,以及未来可能的研究方向,如混合调制方案、自适应调制技术和纳米机器协作协议等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值