博客
关于我
Spring源码分析十八:事务实现④ - 事务的回滚
阅读量:503 次
发布时间:2019-03-07

本文共 5289 字,大约阅读时间需要 17 分钟。

事务的回滚机制解析

在Spring事务管理中,回滚机制是一个核心的功能,用于确保事务能够在出现异常时正确进行 rollback。当方法抛出异常时,Spring会调用TransactionAspectSupport#completeTransactionAfterThrowing方法来处理异常,并决定是否进行事务回滚。本文将深入分析事务回滚的逻辑和实现细节。

文章目录

  • 1. 回滚触发机制

    • 1.1 形成事务的必要条件

      • 事务信息不为 null
      • 事务状态不为 completed

在Spring中,事务的回滚主要由以下几部分组成:

1. 回滚触发机制

当方法抛出异常时,Spring会判断是否需要进行事务回滚的条件具体是:

if (txInfo != null && txInfo.getTransactionStatus() != null)

这表示当前线程是否存在一个有效的事务信息。当满足条件时,进一步检查事务属性中的rollbackOn方法来决定是否进行回滚。

默认实现如下:

public boolean rollbackOn(Throwable ex) { return (ex instanceof RuntimeException || ex instanceof Error); }

这意味着,只有当异常是RuntimeExceptionError类型时,才会触发回滚操作。其他类型的异常则不会触发回滚,但这并不意味着事务没有被启用。

2. 回滚操作的具体实现

当决定进行回滚时,Spring会调用底层平台事务管理器的rollback方法来执行回滚操作。具体实现涉及以下几个步骤:

2.1 触发回滚前置操作

在回滚前,Spring会触发注册的TransactionSynchronizationbeforeCompletion方法。这类触发器可以用于执行自定义操作,如日志记录或资源释放等。默认的实现代码如下:

protected final void triggerBeforeCompletion(DefaultTransactionStatus status) { if (status.isNewSynchronization()) { if (status.isDebug()) { logger.trace("Triggering beforeCompletion synchronization"); } TransactionSynchronizationUtils.triggerBeforeCompletion(); }}

这是一个典型的回滚前置处理逻辑。

2.2 实际的回滚逻辑处理

回滚逻辑的核心在于调用底层数据库连接的rollback方法。不过,在具体实现中,Spring使用了三种不同的回滚模式:

2.2.1 状态保存点回滚

当事务存在已保存的状态点时,采用rollbackToHeldSavepoint方法进行回滚。这通常用于嵌入式事务中,以防止外部事务受到内嵌事务异常的影响。代码实现如下:

public void rollbackToHeldSavepoint() throws TransactionException { Object savepoint = getSavepoint(); if (savepoint == null) { throw new TransactionUsageException( "Cannot roll back to savepoint - no savepoint associated with current transaction"); } getSavepointManager().rollbackToSavepoint(savepoint); getSavepointManager().releaseSavepoint(savepoint); setSavepoint(null);}

2.2.2 独立事务回滚

对于独立的事务(没有保存点),Spring直接调用底层数据源的rollback方法。具体实现如下:

protected void doRollback(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); Connection con = txObject.getConnectionHolder().getConnection(); try { if (status.isDebug()) { logger.debug("Rolling back JDBC transaction on Connection [" + con + "]"); } con.rollback(); } catch (SQLException ex) { throw new TransactionSystemException("Could not roll back JDBC transaction", ex); }}

这里直接调用数据库连接的rollback方法来完成事务回滚。

2.2.3 大事务中的回滚标识

在外部事务中,当内嵌事务设置rollbackOnly为true时,遵循JTA规范,只标记为回滚,等待外部事务统一处理。具体实现如下:

protected void doSetRollbackOnly(DefaultTransactionStatus status) { DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() + ] "rollback-only"); } txObject.setRollbackOnly();}

2.3 回滚后的清理工作

在完成回滚操作后,Spring需要清理事务相关资源。这主要包括:

2.3.1 设置完成标记

cleanupAfterCompletion方法进行清理。这个方法主要负责:

private void cleanupAfterCompletion(DefaultTransactionStatus status) { status.setCompleted(); if (status.isNewSynchronization()) { // 清除当前线程的中关于该事务的信息 TransactionSynchronizationManager.clear(); } if (status.isNewTransaction()) { // 清理事务信息 doCleanupAfterCompletion(status.getTransaction()); } if (status.getSuspendedResources() != null) { if (status.isDebug()) { logger.debug("Resuming suspended transaction after completion of inner transaction"); } Object transaction = (status.hasTransaction() ? status.getTransaction() : null); resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources()); }}

其中,resume方法负责恢复挂起的事务。

2.3.2 恢复挂起的事务

如果在回滚过程中有挂起的事务,Spring会在回滚完成后自动恢复该事务。代码如下:

protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder) throws TransactionException { if (resourcesHolder != null) { // 恢复挂起的事务 Object suspendedResources = resourcesHolder.suspendedResources; if (suspendedResources != null) { doResume(transaction, suspendedResources); } List
suspendedSynchronizations = resourcesHolder.suspendedSynchronizations; // 设置事务相关属性 if (suspendedSynchronizations != null) { TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive); TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel); TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly); TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name); doResumeSynchronization(suspendedSynchronizations); } }}

这里的doResume方法负责具体执行事务恢复操作。

通过以上分析可以看出,Spring的事务回滚机制虽然负责核心逻辑,但实际的数据库操作由底层 JDBC 连接管理器完成。这种设计使得 Spring 在事务管理方面保持了高度的灵活性和兼容性。理解这一点对于深入研究Spring的事务管理是非常重要的。

相关标签:Sprin事务管理,TransactionAspectSupport,回滚机制,JDBC事务管理,Spring源码解析

关键词:事务回滚,Spring事务管理,回滚机制,JDBC事务,事务异常处理

转载地址:http://zykcz.baihongyu.com/

你可能感兴趣的文章
python 到大数据开发工程师_如何成为一个大数据开发工程师?
查看>>
python 加密解密(base64, AES)
查看>>
Python 包管理器和 Node.js
查看>>
Python 单词字母顺序不变且所有倒排
查看>>
python 启动提示IDLE's subprocess didn't make conne...
查看>>
python 命令接口_实现“[命令][操作][参数]”样式的命令行接口?
查看>>
Python 和 OpenCV.如何检测图像中的所有(填充)圆形/圆形对象?
查看>>
Python 和 RabbitMQ - 聆听来自多个渠道的消费事件的最佳方式?
查看>>
python编辑器打不开_关于命令ride.py打不开RF,而是打开pycharm编辑器问题解决思路...
查看>>
python编译exe同时支持32位_第三周:同时管理64位和32位版本的Python,并用Pyinstaller打包成exe...
查看>>
Python 和Java 哪个更适合做自动化测试?
查看>>
Python编程:掌握高级语言程序设计。从零基础到精通,收藏这篇就够了!
查看>>
python 图片转ico
查看>>
python 图片转文字、语音转文字、文字转语音保存音频并朗读
查看>>
python 在包含类似字符\x16、\x12、\x某某的数组中将以\x开头的字符找出来的方法
查看>>
Python 在并行进程之间共享字典
查看>>
Python 垃圾收集器文档
查看>>
python 基于 wordcloud + jieba + matplotlib 生成词云
查看>>
python 基于detectron或mask_rcnn的mask遮罩区域进行图片截取
查看>>
Python编程:Tkinter图形界面设计(2)
查看>>