事务回滚原理

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

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

# 源码分析

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

TransactionalTestExecutionListener

伪代码分析


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

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

全部回复

上滑加载中

设置昵称

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

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

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