事务回滚原理

举报
西魏陶渊明 发表于 2022/09/25 01:18:38 2022/09/25
1.6k+ 0 0
【摘要】 在前文单测类注入中我们知道.JUnit提供了一些监听器,允许 当单测方法执行时候去对单测上下文进行调整。所以呢事务回滚也是基于 这里的特性完成的。 基于SpringBoot 2.1.x版本分析 # 源码分析 Spring中为了适配不通的数据库,提供了事务平台的概念。 PlatformTransacti...

在前文单测类注入中我们知道.JUnit提供了一些监听器,允许 当单测方法执行时候去对单测上下文进行调整。所以呢事务回滚也是基于 这里的特性完成的。 基于SpringBoot 2.1.x版本分析

# 源码分析

Spring中为了适配不通的数据库,提供了事务平台的概念。 PlatformTransactionManager 只要实现了该接口 就允许对事务进行控制。具体事务的控制是通过工具类来处理的。 TransactionContextHolder 可以获取当前线程 执行的事务上下文。JUnit通过该工具拿到事务的上下文,然后对此做响应的修改。具体的 修改逻辑见下文注释。两句话解释清楚。

TransactionalTestExecutionListener

伪代码分析


        // 单测方法执行前,移除容器原来的事务管理器,然后开启一个新的事务
           @Override
       	public void beforeTestMethod(final TestContext testContext) throws Exception {
       		Method testMethod = testContext.getTestMethod();
        		Class<?> testClass = testContext.getTestClass();
        		Assert.notNull(testMethod, "Test method of supplied TestContext must not be null");
       		TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext();
        		Assert.state(txContext == null, "Cannot start new transaction without ending existing transaction");
       		PlatformTransactionManager tm = null;
       		TransactionAttribute transactionAttribute = this.attributeSource.getTransactionAttribute(testMethod, testClass);
       		if (transactionAttribute != null) {
        			transactionAttribute = TestContextTransactionUtils.createDelegatingTransactionAttribute(testContext,
        				transactionAttribute);
       			if (logger.isDebugEnabled()) {
        				logger.debug("Explicit transaction definition [" + transactionAttribute +
       						"] found for test context " + testContext);
        			}
       			if (transactionAttribute.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
       				return;
        			}
        			tm = getTransactionManager(testContext, transactionAttribute.getQualifier());
        			Assert.state(tm != null,
        					() -> "Failed to retrieve PlatformTransactionManager for @Transactional test: " + testContext);
        		}
       		if (tm != null) {
        			txContext = new TransactionContext(testContext, tm, transactionAttribute, isRollback(testContext));
        			runBeforeTransactionMethods(testContext);
        			txContext.startTransaction();
        			TransactionContextHolder.setCurrentTransactionContext(txContext);
        		}
        	}
       	// 单测方法执行结束后,结束事务然后回滚或提交
       	@Override
       	public void afterTestMethod(TestContext testContext) throws Exception {
       		Method testMethod = testContext.getTestMethod();
        		Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null");
       		TransactionContext txContext = TransactionContextHolder.removeCurrentTransactionContext();
       		// If there was (or perhaps still is) a transaction...
       		if (txContext != null) {
       			TransactionStatus transactionStatus = txContext.getTransactionStatus();
       			try {
       				// If the transaction is still active...
       				if (transactionStatus != null && !transactionStatus.isCompleted()) {
        					txContext.endTransaction();
        				}
        			}
       			finally {
        				runAfterTransactionMethods(testContext);
        			}
        		}
        	}
    
   
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

文章来源: springlearn.blog.csdn.net,作者:西魏陶渊明,版权归原作者所有,如需转载,请联系作者。

原文链接:springlearn.blog.csdn.net/article/details/125858104

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。