Spring声明式事务@Transactional注解实现元数据驱动的事务管理
@Transactional 注解元数据驱动的声明式事务
基本原理
将对应的方法通过注解元数据,标注在业务方法或者所在的对象上,然后在业务执行期间,通过AOP拦截器反射读取元数据信息,最终将根据读取的业务信息构建事务管理支持。
不同的方法之间的事务传播保证在同一个事务内,是通过统一的数据源来实现的,事务开始时将数据源绑定到ThreadLocal中,后续加入的事务从ThreadLocal获取数据源来保证数据源的统一。
@Target({ElementType.METHOD, ElementType.TYPE}) @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 {}; }
SpringBoot代码来分析
这里通过SpringBoot代码来分析实现过程,源码中删除了部分代码,只保留了一些重要部分
// 事务自动配置类 注意类里面使用的@EnableTransactionManagement注解 org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration public class TransactionAutoConfiguration { @Configuration @ConditionalOnBean(PlatformTransactionManager.class) @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class) public static class EnableTransactionManagementConfiguration { //注意这里使用的@EnableTransactionManagement注解 @Configuration @EnableTransactionManagement(proxyTargetClass = false) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) public static class JdkDynamicAutoProxyConfiguration { } //注意这里使用的@EnableTransactionManagement注解 @Configuration @EnableTransactionManagement(proxyTargetClass = true) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) public static class CglibAutoProxyConfiguration { } } }
这里只分析proxy模式
@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(); } //这里注入了TransactionInterceptor拦截器bean~~~~ @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; } }
TransactionInterceptor拦截器通过元数据获取事务定义信息TransactionDefinition,根据Definition信息获取PlatformTransactionManager(TM),tm接口抽象了事务的实现流程,默认的tm是DataSourceTransactionManager(通过DataSourceTransactionManagerAutoConfiguration初始化的),tm中的getTransaction根据事务的传播方式,开启、加入、挂起事务
@Override public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException { Object transaction = doGetTransaction(); boolean debugEnabled = logger.isDebugEnabled(); if (definition == null) { // 使用默认的Definition definition = new DefaultTransactionDefinition(); } if (isExistingTransaction(transaction)) { //已经存在事务,进入单独的方法处理 return handleExistingTransaction(definition, transaction, debugEnabled); } // 检查timeout参数 if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout()); } // 当前必须存在事务,否则抛出异常 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); try { boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); //构造一个新事务的TransactionStatus(包含嵌套事务SavePoint的支持) DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); //开启新的事务 doBegin(transaction, definition); prepareSynchronization(status, definition); return status; } catch (RuntimeException | Error ex) { //异常,恢复挂起的事务信息 resume(null, suspendedResources); throw ex; } } else { //空的事务 boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null); } }
以上就是Spring声明式事务@Transactional注解实现元数据驱动的事务管理的详细内容,更多关于Spring @Transactional事务的资料请关注脚本之家其它相关文章!
相关文章
java如何通过FileOutputStream字节流向文件中写数据
这篇文章主要介绍了java如何通过FileOutputStream字节流向文件中写数据问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-12-12
最新评论