java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > spring 事务

spring 事务实现的示例

作者:yingjuxia.com

本文主要介绍了spring 事务实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Spring 的事务实现本质上是基于 AOP(面向切面编程) + 动态代理,在不修改原有业务代码的情况下,把事务的开始、提交、回滚、异常处理这些横切关注点“织入”到目标方法中。

下面从最核心的几个层面逐步拆解(以声明式事务 @Transactional 为例,这是 95%+ 项目实际使用的模式):

1. 整体架构分层(最重要的一张思维导图)

Spring 事务抽象层(PlatformTransactionManager)
          ↑
    具体实现(DataSourceTransactionManager / JpaTransactionManager / JtaTransactionManager 等)
          ↑
   TransactionSynchronizationManager(线程本地资源管理器)
          ↑
   AOP 切面(TransactionInterceptor + 各种 Advice)
          ↑
   动态代理(JDK Proxy / CGLIB)
          ↑
   你的业务 Bean(@Service 中的 @Transactional 方法)

2. 核心实现步骤(运行时发生了什么)

阶段发生了什么关键类 / 组件
容器启动解析 @EnableTransactionManagement 或 <tx:annotation-driven/>TransactionManagementConfigurer / AnnotationDrivenBeanDefinitionParser
注册 BeanFactoryTransactionAttributeSourceAdvisor(事务切面 Advisor)
Bean 创建对于有 @Transactional 的类/方法,Spring 创建代理对象ProxyFactory / CglibAopProxy / JdkDynamicAopProxy
外部调用方法时调用的是代理对象的方法(不是原始对象)
代理拦截TransactionInterceptor(核心 Advice)被执行TransactionInterceptor.invoke()
读取 @Transactional 的属性(propagation、isolation、timeout、rollbackFor 等)TransactionAttributeSource
事务开始调用 PlatformTransactionManager.getTransaction(definition)→ 创建 / 加入 / 挂起事务
把 Connection / TransactionStatus 绑定到 ThreadLocalTransactionSynchronizationManager.bindResource()
目标方法执行真正执行你的业务代码(原始对象的方法)
正常结束提交:commit()TransactionManager.commit(status)
异常抛出判断是否需要回滚(默认 RuntimeException & Error 回滚,可自定义 rollbackFor)rollbackOn() 判断
回滚:rollback()TransactionManager.rollback(status)
清理解绑 ThreadLocal 资源,恢复挂起的旧事务(如果有嵌套)cleanupTransaction()

3. 传播行为(Propagation)是怎么实现的?(最常考点)

传播级别代码中是否有事务外面有事务吗?实际效果底层实现方式简述
REQUIRED新开事务getTransaction() 创建新事务
REQUIRED加入已有事务复用已有 TransactionStatus
REQUIRES_NEW总是新建独立事务(外面事务被挂起)suspend() → create new → resume()
NESTED使用 savepoint(嵌套子事务)createSavepoint() / rollbackToSavepoint()
SUPPORTS跟随外面事务,没有就不用事务只读模式或无事务
MANDATORY抛异常(必须在事务中调用)检查当前是否有事务,没有就 IllegalState
NEVER抛异常(禁止在事务中调用)同上
NOT_SUPPORTED挂起外面事务,以非事务方式执行suspend() → 执行 → resume()

注意:NESTED 是唯一基于 savepoint 的传播行为,其他的都是基于 Connection 的 commit/rollback。

4. 为什么自调用(this.method())事务会失效?

因为代理只对外部调用有效

@Service
public class UserService {

    @Transactional
    public void outer() {
        // 这里有事务
        inner();           // ← this.inner() 直接调用原始对象的方法 → 绕过代理 → 无事务
    }

    @Transactional
    public void inner() {
        // 期望有事务,但实际没有(自调用场景)
    }
}

解决办法(任选其一):

5. 线程安全 & 资源绑定核心 —— TransactionSynchronizationManager

这是一个ThreadLocal大管家,里面存了:

几乎所有事务相关的操作最终都会走到这里取/放资源。

总结一句话

Spring 事务的实现可以浓缩为:

“用动态代理(AOP)拦截方法 → 根据 @Transactional 属性通过 PlatformTransactionManager 在 ThreadLocal 中绑定/管理数据库连接和事务状态 → 在方法正常结束或异常时统一 commit/rollback”。

最核心的两句话:

如果你想更深入看某一块(比如 savepoint 实现细节、DataSourceTransactionManager 源码、Reactive 事务区别、多数据源切换等),可以告诉我,我可以继续拆更细。

到此这篇关于spring 事务实现的示例的文章就介绍到这了,更多相关spring 事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文