Spring事务抽象的是事务管理和事务策略。而实现则由各种资源方实现的。我们最常用的数据库实现:DataSourceTransactionManager

尝试阅读一下spring 的实现代码,由3个核心类:

1,PlatformTransactionManager

  1. public interface PlatformTransactionManager {
  2.  
  3. TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
  4. void commit(TransactionStatus status) throws TransactionException;
  5.  
  6. void rollback(TransactionStatus status) throws TransactionException;

事务管理的抽象,一个获取事务状态,一个提交事务,一个回滚事务。

2,TransactionStatus

  1. public interface TransactionStatus extends SavepointManager, Flushable {
  2.  
  3. boolean isNewTransaction();
  4.  
  5. boolean hasSavepoint();
  6.  
  7. void setRollbackOnly();
  8.  
  9. boolean isRollbackOnly();
  10.  
  11. void flush();
  12.  
  13. boolean isCompleted();
  14.  
  15. }

事务状态的抽象

3,DefaultTransactionDefinition

  1. public interface TransactionDefinition {
  2.  
  3. int getPropagationBehavior();
  4.  
  5. int getIsolationLevel();
  6.  
  7. int getTimeout();
  8.  
  9. boolean isReadOnly();
  10.  
  11. String getName();
  12.  
  13. }

事务策略抽象,1,事务传播行为,2,事务隔离级别,3,超时时间,4,只读属性

编程的方法实现事务管理使用简单代码:

  1. transactionTemplate.execute(new TransactionCallback<String>() {
  2. @Override
  3. public String doInTransaction(TransactionStatus status) {
  4. updatePayPrice(orderData, offer);
  5. return null;
  6. }
  7. });

类似下面的配置:

  1. <bean id="txManager"
  2. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource" />
  4. </bean>
  5.  
  6. <bean id="transactionTemplate"
  7. class="org.springframework.transaction.support.TransactionTemplate"
  8. p:transactionManager-ref="txManager" scope="prototype" />

TransactionTemplate继承了DefaultTransactionDefinition也就是TransactionDefinition默认实现,afterPropertiesSet方法检查transactionManager,

核心方法execute,其中四步:0.获取一个事务状态,1,执行业务逻辑  2,出现异常,3,没有异常事务提交
  1. public class TransactionTemplate extends DefaultTransactionDefinition
  2. implements TransactionOperations, InitializingBean {
  3.  
  4. /** Logger available to subclasses */
  5. protected final Log logger = LogFactory.getLog(getClass());
  6.  
  7. private PlatformTransactionManager transactionManager;
  8. public TransactionTemplate() {
  9. }
  10. public TransactionTemplate(PlatformTransactionManager transactionManager) {
  11. this.transactionManager = transactionManager;
  12. }
  13. public TransactionTemplate(PlatformTransactionManager transactionManager, TransactionDefinition transactionDefinition) {
  14. super(transactionDefinition);
  15. this.transactionManager = transactionManager;
  16. }
  17.  
  18. public void setTransactionManager(PlatformTransactionManager transactionManager) {
  19. this.transactionManager = transactionManager;
  20. }
  21.  
  22. /**
  23. * Return the transaction management strategy to be used.
  24. */
  25. public PlatformTransactionManager getTransactionManager() {
  26. return this.transactionManager;
  27. }
  28.  
  29. @Override
  30. public void afterPropertiesSet() {
  31. if (this.transactionManager == null) {
  32. throw new IllegalArgumentException("Property 'transactionManager' is required");
  33. }
  34. }
  35.  
  36. @Override
  37. public <T> T execute(TransactionCallback<T> action) throws TransactionException {
  38. if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
  39. return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
  40. }
  41. else {
  42. // 0.获取一个事务状态
  43. TransactionStatus status = this.transactionManager.getTransaction(this);
  44. T result;
  45. try {
  46. //1.执行业务逻辑
  47. result = action.doInTransaction(status);
  48. }
  49. // 2.异常则回退
  50. catch (RuntimeException ex) {
  51. // Transactional code threw application exception -> rollback
  52. rollbackOnException(status, ex);
  53. throw ex;
  54. }
  55. catch (Error err) {
  56. // Transactional code threw error -> rollback
  57. rollbackOnException(status, err);
  58. throw err;
  59. }
  60. catch (Exception ex) {
  61. // Transactional code threw unexpected exception -> rollback
  62. rollbackOnException(status, ex);
  63. throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
  64. }
  65. // 3.没有异常事务提交
  66. this.transactionManager.commit(status);
  67. return result;
  68. }
  69. }
  70.  
  71. private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
  72. logger.debug("Initiating transaction rollback on application exception", ex);
  73. try {
  74. this.transactionManager.rollback(status);
  75. }
  76. catch (TransactionSystemException ex2) {
  77. logger.error("Application exception overridden by rollback exception", ex);
  78. ex2.initApplicationException(ex);
  79. throw ex2;
  80. }
  81. catch (RuntimeException ex2) {
  82. logger.error("Application exception overridden by rollback exception", ex);
  83. throw ex2;
  84. }
  85. catch (Error err) {
  86. logger.error("Application exception overridden by rollback error", ex);
  87. throw err;
  88. }
  89. }
  90.  
  91. }
0,获取一个事务状态
this.transactionManager.getTransaction(this);
这里的transactionManager就是前面使用代码的配置中txManager,就是DataSourceTransactionManager,模版类AbstractPlatformTransactionManager。而传参this就是DefaultTransactionDefinition。
下面是AbstractPlatformTransactionManager里的模版方法:
  1. public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
  2. // 进来就先获取事务
  3. Object transaction = doGetTransaction();
  4.  
  5. // Cache debug flag to avoid repeated checks.
  6. // 这里为打日志判断日志级别做的优化,这个在http://www.cnblogs.com/killbug/p/6721047.html 最后有解释。
  7. boolean debugEnabled = logger.isDebugEnabled();
  8.  
  9. if (definition == null) {
  10. // Use defaults if no transaction definition given.
  11. definition = new DefaultTransactionDefinition();
  12. }
  13.  
  14. if (isExistingTransaction(transaction)) {
  15. // Existing transaction found -> check propagation behavior to find out how to behave.
  16. return handleExistingTransaction(definition, transaction, debugEnabled);
  17. }
  18.  
  19. // Check definition settings for new transaction.
  20. if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
  21. throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
  22. }
  23.  
  24. // No existing transaction found -> check propagation behavior to find out how to proceed.
  25. // 配置了PROPAGATION_MANDATORY就不能调用这个方法的,这个方法是开始获取事务的地方
  26. if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
  27. throw new IllegalTransactionStateException(
  28. "No existing transaction found for transaction marked with propagation 'mandatory'");
  29. }
  30. else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
  31. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
  32. definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
  33. // 外层挂起事务时保存的资源
  34. SuspendedResourcesHolder suspendedResources = suspend(null);
  35. if (debugEnabled) {
  36. logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
  37. }
  38. try {
  39. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
  40. // 新建事务
  41. DefaultTransactionStatus status = newTransactionStatus(
  42. definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
  43. doBegin(transaction, definition);
  44. prepareSynchronization(status, definition);
  45. return status;
  46. }
  47. catch (RuntimeException ex) {
  48. resume(null, suspendedResources);
  49. throw ex;
  50. }
  51. catch (Error err) {
  52. resume(null, suspendedResources);
  53. throw err;
  54. }
  55. }
  56. else {
  57. // Create "empty" transaction: no actual transaction, but potentially synchronization.
  58. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
  59. logger.warn("Custom isolation level specified but no actual transaction initiated; " +
  60. "isolation level will effectively be ignored: " + definition);
  61. }
  62. boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
  63. return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
  64. }
  65. }

1,回滚代码:

  1. private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
  2. logger.debug("Initiating transaction rollback on application exception", ex);
  3. try {
  4. this.transactionManager.rollback(status);
  5. }
  6. catch (TransactionSystemException ex2) {
  7. logger.error("Application exception overridden by rollback exception", ex);
  8. ex2.initApplicationException(ex);
  9. throw ex2;
  10. }
  11. catch (RuntimeException ex2) {
  12. logger.error("Application exception overridden by rollback exception", ex);
  13. throw ex2;
  14. }
  15. catch (Error err) {
  16. logger.error("Application exception overridden by rollback error", ex);
  17. throw err;
  18. }
  19. }

transactionManager.rollback

  1. public final void rollback(TransactionStatus status) throws TransactionException {
  2. if (status.isCompleted()) {
  3. throw new IllegalTransactionStateException(
  4. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  5. }
  6.  
  7. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  8. processRollback(defStatus);
  9. }
  10. //模版方法 子类实现自己的会滚操作
  11. private void processRollback(DefaultTransactionStatus status) {
  12. try {
  13. try {
  14. triggerBeforeCompletion(status);
  15. if (status.hasSavepoint()) {
  16. if (status.isDebug()) {
  17. logger.debug("Rolling back transaction to savepoint");
  18. }
  19. status.rollbackToHeldSavepoint();
  20. }
  21. else if (status.isNewTransaction()) {
  22. if (status.isDebug()) {
  23. logger.debug("Initiating transaction rollback");
  24. }
  25. doRollback(status);
  26. }
  27. else if (status.hasTransaction()) {
  28. if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
  29. if (status.isDebug()) {
  30. logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
  31. }
  32. doSetRollbackOnly(status);
  33. }
  34. else {
  35. if (status.isDebug()) {
  36. logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
  37. }
  38. }
  39. }
  40. else {
  41. logger.debug("Should roll back transaction but cannot - no transaction available");
  42. }
  43. }
  44. catch (RuntimeException ex) {
  45. triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
  46. throw ex;
  47. }
  48. catch (Error err) {
  49. triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
  50. throw err;
  51. }
  52. triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
  53. }
  54. finally {
  55. cleanupAfterCompletion(status);
  56. }
  57. }

事务提交:

  1. // 模版
  2. public final void commit(TransactionStatus status) throws TransactionException {
  3. if (status.isCompleted()) {
  4. throw new IllegalTransactionStateException(
  5. "Transaction is already completed - do not call commit or rollback more than once per transaction");
  6. }
  7.  
  8. DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
  9. if (defStatus.isLocalRollbackOnly()) {
  10. if (defStatus.isDebug()) {
  11. logger.debug("Transactional code has requested rollback");
  12. }
  13. processRollback(defStatus);
  14. return;
  15. }
  16. if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
  17. if (defStatus.isDebug()) {
  18. logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
  19. }
  20. processRollback(defStatus);
  21. // Throw UnexpectedRollbackException only at outermost transaction boundary
  22. // or if explicitly asked to.
  23. if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
  24. throw new UnexpectedRollbackException(
  25. "Transaction rolled back because it has been marked as rollback-only");
  26. }
  27. return;
  28. }
  29.  
  30. processCommit(defStatus);
  31. }

AbstractPlatformTransactionManager做为模版类,代码清晰。

我们发现在上面的execute,异常会退时是不没有任何区分什么异常会滚,什么异常不会滚,都是走rollbackOnException。其实我们只要在业务方法中把异常吃掉即可,另外对于回滚后异常抛出,在最外层再把异常做处理。

本篇没有真正深入了解原理实现,写在这里是为了开个头。

spring事务管理-Spring 源码系列(6)的更多相关文章

  1. 【spring源码学习】spring的事务管理的源码解析

    [一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transact ...

  2. spring事务传播实现源码分析

    转载. https://blog.csdn.net/qpfjalzm123/article/details/83717367 本文只是对spring事务传播实现的流程进行简单的分析,如有不对之处请指出 ...

  3. Mybatis整合Spring实现事务管理的源码分析

    一:前言 没有完整看完,但是看到了一些关键的地方,这里做个记录,过程会有点乱,以后逐渐补充最终归档为完整流程:相信看过框架源码的都知道过程中无法完全确定是怎样的流程,毕竟不可能全部都去测试一遍 ,但是 ...

  4. spring事务管理学习

    spring事务管理学习 spring的事务管理和mysql自己的事务之间的区别 参考很好介绍事务异常回滚的文章 MyBatis+Spring 事务管理 spring中的事务回滚例子 这篇文章讲解了@ ...

  5. spring事务管理实现原理-源码-传播属性

    转载请标识 https://me.csdn.net/wanghaitao4j https://blog.csdn.net/wanghaitao4j/article/details/83625260 本 ...

  6. SSM(spring mvc+spring+mybatis)学习路径——1-2、spring事务管理

    目录 1-2 Spring事务管理 概念介绍 事务回顾 事务的API介绍 Spring 事务管理 转账案例 编程式事务管理 声明式事务管理 使用XML配置声明式事务 基于tx/aop 使用注解配置声明 ...

  7. 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)

    Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...

  8. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

  9. Spring源码系列(三)--spring-aop的基础组件、架构和使用

    简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...

  10. Spring源码系列(四)--spring-aop是如何设计的

    简介 spring-aop 用于生成动态代理类(底层是使用 JDK 动态代理或 cglib 来生成代理类),搭配 spring-bean 一起使用,可以使 AOP 更加解耦.方便.在实际项目中,spr ...

随机推荐

  1. 部署java项目到服务器

    1.首先判断服务器是什么系统 linux,windows 2.如果是linux使用SSH进行链接 3.如果是windows使用远程桌面进行链接 1.windows+R->mstsc进行远程桌面的 ...

  2. Linux查看某个命令属于哪个包

    有时修我们需要某个命令但其没有安装,提供该命令的包名也与命令名相差很大直接查找命令名找不到包,如rexec. 此时我们就非常需要这样一个工具:可以根据最终的命令查找提供该命令的软件包. 类型 命令 说 ...

  3. 基于spring的PropertySource类实现配置的动态替换

    public class ConfigPropertySource extends PropertySource<Properties> implements PriorityOrdere ...

  4. possible error

    1● regedit 2● path [HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Windows Error Reporting]       3● 步 ...

  5. ubuntu 挂载虚拟机vdi文件

    sudo apt-get  install nbd-server  nbd-client  qemu-kvm # rmmod nbd # modprobe nbd max_part=8 # qemu- ...

  6. linux下sed命令详解

    sed:Stream Editor文本流编辑,sed是一个“非交互式的”面向字符流的编辑器.能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上 ...

  7. CString 转换为 wchar_t *

    1.将CString转换为const char* CString str = _T("231222"); std::string strDp = CStringA(str);  / ...

  8. linux command mktemp

    Linux command mktemp [Purpose]        Learning linux command mktemp to create a temporary file or di ...

  9. Linux系统从零到高手的进阶心得

    初次了解到Linux系统还是在我初中的时候,那时候正是在一个中二年龄,喜欢看小说,对于小说中出现的明显的非现实场景感到十分钦佩.羡慕,并常常幻想自己也有小说主人公那样的本领.那正是在这样一个充满幻想的 ...

  10. FFT模板(无讲解)

    #include<bits/stdc++.h> using namespace std; ; const double pi=3.1415926535898; ],len; struct ...