共计 23417 个字符,预计需要花费 59 分钟才能阅读完成。
序
本文主要研究一下 spring tx 的 EnableTransactionManagement
EnableTransactionManagement
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/EnableTransactionManagement.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as
* opposed to standard Java interface-based proxies ({@code false}). The default is
* {@code false}. <strong>Applicable only if {@link #mode()} is set to
* {@link AdviceMode#PROXY}</strong>.
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
* Spring-managed beans requiring proxying, not just those marked with
* {@code @Transactional}. For example, other beans marked with Spring’s
* {@code @Async} annotation will be upgraded to subclass proxying at the same
* time. This approach has no negative impact in practice unless one is explicitly
* expecting one type of proxy vs another, e.g. in tests.
*/
boolean proxyTargetClass() default false;
/**
* Indicate how transactional advice should be applied.
* <p><b>The default is {@link AdviceMode#PROXY}.</b>
* Please note that proxy mode allows for interception of calls through the proxy
* only. Local calls within the same class cannot get intercepted that way; an
* {@link Transactional} annotation on such a method within a local call will be
* ignored since Spring’s interceptor does not even kick in for such a runtime
* scenario. For a more advanced mode of interception, consider switching this to
* {@link AdviceMode#ASPECTJ}.
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
* Indicate the ordering of the execution of the transaction advisor
* when multiple advices are applied at a specific joinpoint.
* <p>The default is {@link Ordered#LOWEST_PRECEDENCE}.
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
EnableTransactionManagement 有三个属性,分别是 proxyTargetClass、AdviceMode、order;它 import 了 TransactionManagementConfigurationSelector
proxyTargetClass 设置为 true 表示使用基于子类实现的代理 (CGLIB),设置为 false 表示使用基于接口实现的代理,默认为 false
AdviceMode 表示是使用哪种 transactional advice,有 PROXY 及 ASPECTJ 两种,默认是 AdviceMode.PROXY
TransactionManagementConfigurationSelector
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/TransactionManagementConfigurationSelector.java
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* Returns {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
* and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
* respectively.
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
private String determineTransactionAspectClass() {
return (ClassUtils.isPresent(“javax.transaction.Transactional”, getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}
}
TransactionManagementConfigurationSelector 继承了抽象类 AdviceModeImportSelector,它覆盖了 selectImports,该方法根据 adviceMode 返回要创建的类名;如果是 PROXY 模式,则返回 AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName();如果是 ASPECTJ 模式,则返回 TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME 或者是 TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
AbstractTransactionManagementConfiguration
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/AbstractTransactionManagementConfiguration.java
@Configuration
public abstract class AbstractTransactionManagementConfiguration implements ImportAware {
@Nullable
protected AnnotationAttributes enableTx;
/**
* Default transaction manager, as configured through a {@link TransactionManagementConfigurer}.
*/
@Nullable
protected PlatformTransactionManager txManager;
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableTx = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
if (this.enableTx == null) {
throw new IllegalArgumentException(
“@EnableTransactionManagement is not present on importing class ” + importMetadata.getClassName());
}
}
@Autowired(required = false)
void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException(“Only one TransactionManagementConfigurer may exist”);
}
TransactionManagementConfigurer configurer = configurers.iterator().next();
this.txManager = configurer.annotationDrivenTransactionManager();
}
@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public static TransactionalEventListenerFactory transactionalEventListenerFactory() {
return new TransactionalEventListenerFactory();
}
}
AbstractTransactionManagementConfiguration 为 EnableTransactionManagement 注解提供了通用的结构,这里主要是初始化了 txManager,以及创建了 TransactionalEventListenerFactory;它有三个子类,分别是 ProxyTransactionManagementConfiguration、AspectJTransactionManagementConfiguration、AspectJJtaTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.java
@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());
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;
}
}
ProxyTransactionManagementConfiguration 继承了 AbstractTransactionManagementConfiguration,这里它注册了 BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource(AnnotationTransactionAttributeSource)、TransactionInterceptor
AnnotationTransactionAttributeSource
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/annotation/AnnotationTransactionAttributeSource.java
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {
private static final boolean jta12Present;
private static final boolean ejb3Present;
static {
ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();
jta12Present = ClassUtils.isPresent(“javax.transaction.Transactional”, classLoader);
ejb3Present = ClassUtils.isPresent(“javax.ejb.TransactionAttribute”, classLoader);
}
private final boolean publicMethodsOnly;
private final Set<TransactionAnnotationParser> annotationParsers;
/**
* Create a default AnnotationTransactionAttributeSource, supporting
* public methods that carry the {@code Transactional} annotation
* or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
*/
public AnnotationTransactionAttributeSource() {
this(true);
}
/**
* Create a custom AnnotationTransactionAttributeSource, supporting
* public methods that carry the {@code Transactional} annotation
* or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
* @param publicMethodsOnly whether to support public methods that carry
* the {@code Transactional} annotation only (typically for use
* with proxy-based AOP), or protected/private methods as well
* (typically used with AspectJ class weaving)
*/
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
//……
}
AnnotationTransactionAttributeSource 的无参构造器,设置了 publicMethodsOnly 为 true,同时创建了 SpringTransactionAnnotationParser
TransactionInterceptor
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionInterceptor.java
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
/**
* Create a new TransactionInterceptor.
* <p>Transaction manager and transaction attributes still need to be set.
* @see #setTransactionManager
* @see #setTransactionAttributes(java.util.Properties)
* @see #setTransactionAttributeSource(TransactionAttributeSource)
*/
public TransactionInterceptor() {
}
/**
* Create a new TransactionInterceptor.
* @param ptm the default transaction manager to perform the actual transaction management
* @param attributes the transaction attributes in properties format
* @see #setTransactionManager
* @see #setTransactionAttributes(java.util.Properties)
*/
public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
setTransactionManager(ptm);
setTransactionAttributes(attributes);
}
/**
* Create a new TransactionInterceptor.
* @param ptm the default transaction manager to perform the actual transaction management
* @param tas the attribute source to be used to find transaction attributes
* @see #setTransactionManager
* @see #setTransactionAttributeSource(TransactionAttributeSource)
*/
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport’s invokeWithinTransaction…
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
//———————————————————————
// Serialization support
//———————————————————————
private void writeObject(ObjectOutputStream oos) throws IOException {
// Rely on default serialization, although this class itself doesn’t carry state anyway…
oos.defaultWriteObject();
// Deserialize superclass fields.
oos.writeObject(getTransactionManagerBeanName());
oos.writeObject(getTransactionManager());
oos.writeObject(getTransactionAttributeSource());
oos.writeObject(getBeanFactory());
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
// Rely on default serialization, although this class itself doesn’t carry state anyway…
ois.defaultReadObject();
// Serialize all relevant superclass fields.
// Superclass can’t implement Serializable because it also serves as base class
// for AspectJ aspects (which are not allowed to implement Serializable)!
setTransactionManagerBeanName((String) ois.readObject());
setTransactionManager((PlatformTransactionManager) ois.readObject());
setTransactionAttributeSource((TransactionAttributeSource) ois.readObject());
setBeanFactory((BeanFactory) ois.readObject());
}
}
TransactionInterceptor 继承了抽象类 TransactionAspectSupport,同时实现了 MethodInterceptor, Serializable 接口;其 invoke 方法首先读取 targetClass,然后调用了抽象类 TransactionAspectSupport 的 invokeWithinTransaction 方法
TransactionAspectSupport
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
// NOTE: This class must not implement Serializable because it serves as base
// class for AspectJ aspects (which are not allowed to implement Serializable)!
private static final Object DEFAULT_TRANSACTION_MANAGER_KEY = new Object();
private static final ThreadLocal<TransactionInfo> transactionInfoHolder =
new NamedThreadLocal<>(“Current aspect-driven transaction”);
@Nullable
protected static TransactionInfo currentTransactionInfo() throws NoTransactionException {
return transactionInfoHolder.get();
}
public static TransactionStatus currentTransactionStatus() throws NoTransactionException {
TransactionInfo info = currentTransactionInfo();
if (info == null || info.transactionStatus == null) {
throw new NoTransactionException(“No transaction aspect-managed TransactionStatus in scope”);
}
return info.transactionStatus;
}
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private String transactionManagerBeanName;
@Nullable
private PlatformTransactionManager transactionManager;
@Nullable
private TransactionAttributeSource transactionAttributeSource;
@Nullable
private BeanFactory beanFactory;
private final ConcurrentMap<Object, PlatformTransactionManager> transactionManagerCache =
new ConcurrentReferenceHashMap<>(4);
//……
/**
* General delegate for around-advice-based subclasses, delegating to several other template
* methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
* as well as regular {@link PlatformTransactionManager} implementations.
* @param method the Method being invoked
* @param targetClass the target class that we’re invoking the method on
* @param invocation the callback to use for proceeding with the target invocation
* @return the return value of the method, if any
* @throws Throwable propagated from the target invocation
*/
@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
final 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;
}
else {
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It’s a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
try {
return invocation.proceedWithInvocation();
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error(“Application exception overridden by commit exception”, throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error(“Application exception overridden by commit exception”, throwableHolder.throwable);
}
throw ex2;
}
}
}
//……
}
TransactionAspectSupport 的 invokeWithinTransaction 方法对于 TransactionAttribute 不为 null 且 PlatformTransactionManager 是 CallbackPreferringPlatformTransactionManager 类型的在 TransactionCallback 中事务处理;其他的则使用标准的 getTransaction and commit/rollback calls 模式来进行事务处理,执行前调用 createTransactionIfNecessary,异常时调用 completeTransactionAfterThrowing,finally 时调用 cleanupTransactionInfo,最后调用 commitTransactionAfterReturning
createTransactionIfNecessary
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/**
* Create a transaction if necessary based on the given TransactionAttribute.
* <p>Allows callers to perform custom TransactionAttribute lookups through
* the TransactionAttributeSource.
* @param txAttr the TransactionAttribute (may be {@code null})
* @param joinpointIdentification the fully qualified method name
* (used for monitoring and logging purposes)
* @return a TransactionInfo object, whether or not a transaction was created.
* The {@code hasTransaction()} method on TransactionInfo can be used to
* tell if there was a transaction created.
* @see #getTransactionAttributeSource()
*/
@SuppressWarnings(“serial”)
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable 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);
}
/**
* Prepare a TransactionInfo for the given attribute and status object.
* @param txAttr the TransactionAttribute (may be {@code null})
* @param joinpointIdentification the fully qualified method name
* (used for monitoring and logging purposes)
* @param status the TransactionStatus for the current transaction
* @return the prepared TransactionInfo object
*/
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
if (txAttr != null) {
// We need a transaction for this method…
if (logger.isTraceEnabled()) {
logger.trace(“Getting transaction for [” + txInfo.getJoinpointIdentification() + “]”);
}
// The transaction manager will flag an error if an incompatible tx already exists.
txInfo.newTransactionStatus(status);
}
else {
// The TransactionInfo.hasTransaction() method will return false. We created it only
// to preserve the integrity of the ThreadLocal stack maintained in this class.
if (logger.isTraceEnabled()) {
logger.trace(“Don’t need to create transaction for [” + joinpointIdentification +
“]: This method isn’t transactional.”);
}
}
// We always bind the TransactionInfo to the thread, even if we didn’t create
// a new transaction here. This guarantees that the TransactionInfo stack
// will be managed correctly even if no transaction was created by this aspect.
txInfo.bindToThread();
return txInfo;
}
createTransactionIfNecessary 方法基于 TransactionAttribute 判断是否需要新创建 transaction,然后执行 prepareTransactionInfo 创建 TransactionInfo 并 bindToThread
completeTransactionAfterThrowing
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/**
* Handle a throwable, completing the transaction.
* We may commit or roll back, depending on the configuration.
* @param txInfo information about the current transaction
* @param ex throwable encountered
*/
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 {
// 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) {
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;
}
}
}
}
completeTransactionAfterThrowing 用于处理异常情况,它根据 TransactionInfo 及 Throwable 信息判断是要 rollback 还是 commit
cleanupTransactionInfo
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/**
* Reset the TransactionInfo ThreadLocal.
* <p>Call this in all cases: exception or normal return!
* @param txInfo information about the current transaction (may be {@code null})
*/
protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {
if (txInfo != null) {
txInfo.restoreThreadLocalStatus();
}
}
cleanupTransactionInfo 用于重置 ThreadLocal 的 TransactionInfo
commitTransactionAfterReturning
spring-tx-5.1.6.RELEASE-sources.jar!/org/springframework/transaction/interceptor/TransactionAspectSupport.java
/**
* Execute after successful completion of call, but not after an exception was handled.
* Do nothing if we didn’t create a transaction.
* @param txInfo information about the current transaction
*/
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());
}
}
commitTransactionAfterReturning 用于在方法执行成功时来 commit 事务
小结
EnableTransactionManagement 有三个属性,分别是 proxyTargetClass、AdviceMode、order;它 import 了 TransactionManagementConfigurationSelector;proxyTargetClass 设置为 true 表示使用基于子类实现的代理 (CGLIB),设置为 false 表示使用基于接口实现的代理,默认为 false;AdviceMode 表示是使用哪种 transactional advice,有 PROXY 及 ASPECTJ 两种,默认是 AdviceMode.PROXY
TransactionManagementConfigurationSelector 继承了抽象类 AdviceModeImportSelector,它覆盖了 selectImports,该方法根据 adviceMode 返回要创建的类名;如果是 PROXY 模式,则返回 AutoProxyRegistrar.class.getName(),ProxyTransactionManagementConfiguration.class.getName();如果是 ASPECTJ 模式,则返回 TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME 或者是 TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
ProxyTransactionManagementConfiguration 继承了 AbstractTransactionManagementConfiguration,这里它注册了 BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource(AnnotationTransactionAttributeSource)、TransactionInterceptor
TransactionInterceptor 继承了抽象类 TransactionAspectSupport,同时实现了 MethodInterceptor, Serializable 接口;其 invoke 方法首先读取 targetClass,然后调用了抽象类 TransactionAspectSupport 的 invokeWithinTransaction 方法
TransactionAspectSupport 的 invokeWithinTransaction 方法对于 TransactionAttribute 不为 null 且 PlatformTransactionManager 是 CallbackPreferringPlatformTransactionManager 类型的在 TransactionCallback 中事务处理;其他的则使用标准的 getTransaction and commit/rollback calls 模式来进行事务处理,执行前调用 createTransactionIfNecessary,异常时调用 completeTransactionAfterThrowing,finally 时调用 cleanupTransactionInfo,最后调用 commitTransactionAfterReturning
doc
5.7. Transactionality
Transactions with Spring and JPA
Using Transactions in Spring Data JPA