专栏首页风中追风源码分析 spring事务处理机制
原创

源码分析 spring事务处理机制

Spring在TransactionDefinition接口中定义这些属性,以供PlatfromTransactionManager使用, PlatfromTransactionManager是Spring事务管理的核心接口。

接口代码如下:

[java] view plain copy

  1. public interface TransactionDefinition {  
  2. int getPropagationBehavior(); //返回事务的传播行为。 
  3. int getIsolationLevel(); //返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据。
  4. int getTimeout(); //返回事务必须在多少秒内完成。
  5. boolean isReadOnly(); //事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的。 
  6. }  

事务的传播属性有:

PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。(默认的传播属性)

PROPAGATION_REQUIRES_NEW 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。

PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。

PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常;

PROPAGATION_NESTED如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。

当我们的程序调用到 把被 @Transaction 注解修饰的方法时,会被spring的AOP切面拦截,该方法会被进行增强,其中就包含了spring对该方法进行事务管理。spring会对不同的传播属性进行不同的事务处理。spring 通过 AbstractPlatformTransactionManager这个类来管理事务。

方法如下:

[java] view plain copy

  1. public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {    
  2. //doGetTransaction()方法是抽象方法,具体的实现由具体的事务处理器提供  
  3.         Object transaction = doGetTransaction();    
  4. boolean debugEnabled = logger.isDebugEnabled();    
  5. //如果没有配置事务属性,则使用默认的事务属性  
  6. if (definition == null) {    
  7.             definition = new DefaultTransactionDefinition();    
  8.         }    
  9. //检查当前线程是否存在事务  
  10. if (isExistingTransaction(transaction)) {    
  11. //处理已存在的事务  
  12. return handleExistingTransaction(definition, transaction, debugEnabled);    
  13.         }    
  14. //检查事务属性中timeout超时属性设置是否合理  
  15. if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {    
  16. throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());    
  17.         }    
  18. //对事务属性中配置的事务传播特性处理  
  19. //如果事务传播特性配置的是mandatory,当前没有事务存在,抛出异常  
  20. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {    
  21. throw new IllegalTransactionStateException(    
  22. "No existing transaction found for transaction marked with propagation 'mandatory'");    
  23.         }    
  24. //如果事务传播特性为required、required_new或nested  
  25. else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||    
  26.                 definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||    
  27.             definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {    
  28.             SuspendedResourcesHolder suspendedResources = suspend(null);    
  29. if (debugEnabled) {    
  30.                 logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);    
  31.             }    
  32. //创建事务  
  33. try {    
  34. //不激活和当前线程绑定的事务,因为事务传播特性配置要求创建新的事务  
  35. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);    
  36. //创建一个新的事务状态  
  37.                 DefaultTransactionStatus status = newTransactionStatus(    
  38.                         definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);    
  39. //创建事务的调用,具体实现由具体的事务处理器提供  
  40.                 doBegin(transaction, definition);    
  41. //初始化和同步事务状态  
  42.                 prepareSynchronization(status, definition);    
  43. return status;    
  44.             }    
  45. catch (RuntimeException ex) {    
  46.                 resume(null, suspendedResources);    
  47. throw ex;    
  48.             }    
  49. catch (Error err) {    
  50.                 resume(null, suspendedResources);    
  51. throw err;    
  52.             }    
  53.         }    
  54. else {    
  55. //创建空事务,否则就创建一个空事务,没有实际事务,但可能同步。(实际上就是不使用事务)
  56. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);    
  57. //准备事务状态  
  58. return prepareTransactionStatus(definition, nulltrue, newSynchronization, debugEnabled, null);    
  59.         }    
  60.     }    

AbstractPlatformTransactionManager处理已经存在的事务:

  1. private TransactionStatus handleExistingTransaction(    
  2.            TransactionDefinition definition, Object transaction, boolean debugEnabled)    
  3. throws TransactionException {    
  4. //如果事务传播特性为:never,则抛出异常  
  5. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {    
  6. throw new IllegalTransactionStateException(    
  7. "Existing transaction found for transaction marked with propagation 'never'");    
  8.        }    
  9. //如果事务传播特性是not_supported,同时当前线程存在事务,则将事务挂起  
  10. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {    
  11. if (debugEnabled) {    
  12.                logger.debug("Suspending current transaction");    
  13.            }    
  14. //挂起事务  
  15.            Object suspendedResources = suspend(transaction);    
  16. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);    
  17. //创建非事务的事务状态,让方法非事务地执行  
  18. return prepareTransactionStatus(    
  19.                    definition, nullfalse, newSynchronization, debugEnabled, suspendedResources);    
  20.        }    
  21. //如果事务传播特性是required_new,则创建新事务,同时把当前线程中存在的  
  22. /事务挂起    
  23. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {    
  24. if (debugEnabled) {    
  25.                logger.debug("Suspending current transaction, creating new transaction with name [" +    
  26.                        definition.getName() + "]");    
  27.            }    
  28. //挂起已存在的事务  
  29.            SuspendedResourcesHolder suspendedResources = suspend(transaction);    
  30. try {    
  31. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);    
  32. //将挂起的事务状态保存起来  
  33.                DefaultTransactionStatus status = newTransactionStatus(    
  34.                        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);    
  35. //创建新事务  
  36.                doBegin(transaction, definition);    
  37.                prepareSynchronization(status, definition);    
  38. return status;    
  39.            }    
  40. catch (RuntimeException beginEx) {    
  41.                resumeAfterBeginException(transaction, suspendedResources, beginEx);    
  42. throw beginEx;    
  43.            }    
  44. catch (Error beginErr) {    
  45.                resumeAfterBeginException(transaction, suspendedResources, beginErr);    
  46. throw beginErr;    
  47.            }    
  48.        }    
  49. //如果事务传播特性是nested嵌套事务  
  50. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {    
  51. //如果不允许事务嵌套,则抛出异常  
  52. if (!isNestedTransactionAllowed()) {    
  53. throw new NestedTransactionNotSupportedException(    
  54. "Transaction manager does not allow nested transactions by default - " +    
  55. "specify 'nestedTransactionAllowed' property with value 'true'");    
  56.            }    
  57. if (debugEnabled) {    
  58.                logger.debug("Creating nested transaction with name [" + definition.getName() + "]");    
  59.            }    
  60. //如果允许使用savepoint保存点保存嵌套事务  
  61. if (useSavepointForNestedTransaction()) {    
  62. //为当前事务创建一个保存点  
  63.                DefaultTransactionStatus status =    
  64.                        prepareTransactionStatus(definition, transaction, falsefalse, debugEnabled, null);    
  65.                status.createAndHoldSavepoint();    
  66. return status;    
  67.            }    
  68. //如果不允许使用savepoint保存点保存嵌套事务  
  69. else {    
  70. //使用JTA的嵌套commit/rollback调用  
  71. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);    
  72.                DefaultTransactionStatus status = newTransactionStatus(    
  73.                        definition, transaction, true, newSynchronization, debugEnabled, null);    
  74.                doBegin(transaction, definition);    
  75.                prepareSynchronization(status, definition);    
  76. return status;    
  77.            }    
  78.        }    
  79. //对于事务传播特性为supported和required的处理  
  80. if (debugEnabled) {    
  81.            logger.debug("Participating in existing transaction");    
  82.        }    
  83. //校验已存在的事务,如果已有事务与事务属性配置不一致,则抛出异常  
  84. if (isValidateExistingTransaction()) {    
  85. //如果事务隔离级别不是默认隔离级别  
  86. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {    
  87. //获取当前事务的隔离级别  
  88.                Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();    
  89. //如果获取到的当前事务隔离级别为null获取不等于事务属性配置的隔离级别  
  90. if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {    
  91.                    Constants isoConstants = DefaultTransactionDefinition.constants;    
  92. throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));    
  93.                }    
  94.            }    
  95. //如果事务不是只读  
  96. if (!definition.isReadOnly()) {    
  97. //如果当前已有事务是只读  
  98. if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {    
  99. throw new IllegalTransactionStateException("Participating transaction with definition [" +    
  100.                            definition + "] is not marked as read-only but existing transaction is");    
  101.                }    
  102.            }    
  103.        }    
  104. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);    
  105. //返回当前事务的执行状态  
  106. return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);    
  107.    }    

加个抽离无关代码的总结,对流程更清晰一点

下篇将会介绍spring的事务管理如何在日常的开发中更灵活的使用

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 高效编程之hashmap你必须要懂的知识点

    以前看Java的招聘要求:Java基础扎实,熟悉常用集合类,多线程,IO,网络编程,经常会疑惑,集合类不就ArrayList,HashMap会用,熟悉下API不...

    矿泉水
  • java类的加载过程和类加载器的分析

    我们知道,我们写的java代码保存的格式是 .java, java文件被编译后会转换为字节码,字节码可以在任何平台通过java虚拟机来运行,这也是java能够跨...

    矿泉水
  • TCP 三次握手与四次挥手 看了你必懂

    最近在思考一个问题,当我们在浏览器中输入URL按下回车键后,他的详细流程是怎样的;以前刚用springMVC的时候弄懂了一个请求的流程,好几个月以为那就是我想要...

    矿泉水
  • 源码分析 spring事务处理机制

    用户2141593
  • WCF技术剖析之三十一: WCF事务编程[下篇]

    在WCF事务编程模型下,通过服务契约确定事务流转的策略(参阅《上篇》),通过事务绑定实施事务的流转(参阅《中篇》)。但是,对于事务绑定接收到并成功创建的事务来说...

    蒋金楠
  • 分布式事务处理你不得不听的踩坑故事-让你的代码经得起考验

    java架构师
  • mysql 谈谈innodb存储引擎

    5.7版本引入了模式自动转换的功能,但该语法依然保留了。 另外一个有趣的点是,在5.7版本中,你可以通过设置session_track_transactio...

    Java架构师历程
  • MySQL事务原理&实战【官方精译】

    事务隔离是数据库处理的基础之一。隔离是I中的首字母 ACID ; 隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡...

    sunsky
  • 事务的隔离性

    事务的四大特性为原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),本篇专门说说隔离性...

    你的益达
  • mysql之DDL

    一 简介:今天来DDL的变革 二 DDL演化方式: 1 copy table : 1 创建临时表2 copy数据到临时表 3 rename进行交换 缺点...

    梦_之_旅

扫码关注云+社区

领取腾讯云代金券