Spring声明式事务(@Transactional)通过AOP实现过程

 更新时间:2026年05月16日 10:52:43   作者:冰糖心书房  
Spring的声明式事务通过AOP代理技术实现,扫描标记了@Transactional的类或方法,为目标对象创建代理,方法调用时根据配置开启、提交或回滚事务,从而简化事务管理,提高代码复用性和可维护性

Spring 的声明式事务 (@Transactional) 是 AOP 技术最经典的应用之一。

其核心思想是:通过 AOP 代理,在业务代码执行前后,自动地开启、提交或回滚事务。

下面是详细的实现步骤和原理:

Step 1: 扫描与识别

当 Spring 容器启动时:

  • 它会扫描所有的 Bean。
  • 它会寻找被 @Transactional 注解标记的类或方法。
  • 一旦发现某个 Bean(例如 OrderService)中含有 @Transactional 方法,Spring 就会判定这个 Bean 需要事务增强。

Step 2: 创建代理对象

对于需要事务增强的 Bean,Spring 不会直接将原始的 OrderService 实例放入容器。相反,它会:

  • 使用 AOP 框架(具体来说是 TransactionProxyFactoryBean)为这个 OrderService 创建一个代理对象OrderServiceProxy)。
  • 这个代理对象看起来和原始对象一模一样(实现了相同的接口或继承了相同的类),但它的内部包含了额外的事务拦截器 (Transaction Interceptor)
  • 最终,当其他组件(如 Controller)通过 @Autowired 注入 OrderService 时,它们实际得到的是这个代理对象

Step 3: 方法调用与拦截 (核心)

当你的代码调用一个被 @Transactional 注解的方法时(例如 orderServiceProxy.placeOrder()),这个调用过程会遵循一个典型的环绕通知 (@Around) 流程:

调用被代理对象拦截

你的调用首先到达的是 OrderServiceProxy,而不是原始的 OrderService

事务拦截器 (Transaction Interceptor) 被激活

代理对象中的事务拦截器(可以看作一个环绕通知)开始工作。它的逻辑如下:

a. 【方法执行前】准备事务环境:

  • * 获取 PlatformTransactionManager(事务管理器,如 DataSourceTransactionManager)。
  • * 检查当前是否存在一个已激活的事务。
  • * 根据 @Transactional 注解中配置的传播行为 (Propagation) 来决定下一步操作。例如:
  • * REQUIRED (默认):如果当前没事务,就开启一个新事务 (connection.setAutoCommit(false));如果已有事务,就加入它。
  • * REQUIRES_NEW挂起当前事务(如果存在),并总是开启一个全新的事务
  • * 根据注解配置设置事务的隔离级别 (Isolation)超时时间 (Timeout)只读状态 (Read-Only) 等。

b. 【调用目标方法】执行核心业务逻辑:

  • * 在 try 代码块中,事务拦截器会调用原始的 OrderService 对象的 placeOrder() 方法。
  • * orderRepository.save(order);
  • * stockService.decreaseStock(order.getProductId());
  • * 你的所有业务代码都在这个事务的保护下执行。

c. 【方法成功返回后】提交事务:

  • * 如果目标方法成功执行完毕,没有抛出任何异常,try 块正常结束。
  • * 事务拦截器会捕获到这个成功的状态,然后调用 transactionManager.commit()提交事务

d. 【方法抛出异常后】回滚事务:

  • * 如果目标方法在执行过程中抛出了异常,这个异常会被 catch 块捕获。
  • * 事务拦截器会检查这个异常的类型。根据 @Transactional 注解的回滚规则 (Rollback Rules)
  • * 默认情况下,如果抛出的是 RuntimeExceptionError,事务拦截器会调用 transactionManager.rollback()回滚事务
  • * 如果抛出的是已检查异常 (Checked Exception),默认不会回滚(这个行为可以配置)。
  • * 回滚后,异常会继续向上层抛出,以便调用方可以感知到错误。

图解实现原理

+----------------+
| Controller     |
+----------------+
        | 1. 调用 orderService.placeOrder()
        v
+-----------------------------------------------------------------------------+
|              OrderService 代理对象 (Proxy)                                   |
|                                                                             |
|   +---------------------------------------------------------------------+   |
|   |             事务拦截器 (Transaction Interceptor - Around Advice)      |   |
|   |                                                                     |   |
|   |    2. 【方法执行前】                                                  |   |
|   |       - 获取事务管理器                                                |   |
|   |       - 根据传播行为,开启新事务 (connection.setAutoCommit(false))     |   |
|   |                                                                     |   |
|   |    3. 【调用目标方法】try {                                           |   |
|   |           target.placeOrder(); <---------------------------------+    |   |
|   |       }                                                          |    |   |
|   |                                                                  |    |   |
|   |    4a. 【成功返回后】catch (no exception) {                        |    |   |
|   |            transactionManager.commit(); // 提交事务              |    |   |
|   |        }                                                         |    |   |
|   |                                                                  |    |   |
|   |    4b. 【抛出异常后】catch (RuntimeException | Error) {             |    |   |
|   |            transactionManager.rollback(); // 回滚事务             |    |   |
|   |            throw ex; // 继续抛出异常                             |    |   |
|   |        }                                                         |    |   |
|   |                                                                     |   |
|   +---------------------------------------------------------------------+   |
|                                                                             |
+-----------------------------------------------------------------------------+
        ^                                                               |
        | 5. 最终结果或异常返回给 Controller                             |
        |                                                               |
        |        +--------------------------------------------------------+
        |        |
        v        v
+--------------------------+
|  OrderService 目标对象   |
|  (包含纯粹的业务逻辑)    |
+--------------------------+

总结

  • 核心技术:Spring AOP 的环绕通知 (@Around)

关键角色

  • 代理对象 (Proxy):拦截方法调用。
  • 事务拦截器 (Transaction Interceptor):实现了具体的事务管理逻辑。
  • 事务管理器 (PlatformTransactionManager):执行真正的事务操作(开启、提交、回滚)。

工作流程

  1. 代理拦截:调用被代理对象拦截。
  2. 事务开启:在目标方法执行前,根据配置开启事务。
  3. 业务执行:调用原始目标对象的业务方法。
  4. 事务提交/回滚:根据业务方法的执行结果(成功或异常),决定是提交还是回滚事务。

通过这种方式,AOP 完美地将重复、通用的事务管理代码从核心业务逻辑中剥离出来,实现了高度的解耦和代码的整洁。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解java中的static关键字

    详解java中的static关键字

    这篇文章主要介绍了java中的static关键字的的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 密码系统AES私钥RSA公钥的加解密示例

    密码系统AES私钥RSA公钥的加解密示例

    这篇文章主要为大家诠释并介绍了AES私钥RSA公钥的加解密系统示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-03-03
  • SpringCloud服务接口调用OpenFeign及使用详解

    SpringCloud服务接口调用OpenFeign及使用详解

    这篇文章主要介绍了SpringCloud服务接口调用——OpenFeign,在学习Ribbon时,服务间调用使用的是RestTemplate+Ribbon实现,而Feign在此基础上继续进行了封装,使服务间调用变得更加方便,需要的朋友可以参考下
    2023-04-04
  • Java微服务无损发布生产实战案例及验证

    Java微服务无损发布生产实战案例及验证

    微服务架构是一项在云中部署应用和服务的新技术,这篇文章主要介绍了Java微服务无损发布生产实战及验证的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-10-10
  • 解决Springboot项目打包后的页面丢失问题(thymeleaf报错)

    解决Springboot项目打包后的页面丢失问题(thymeleaf报错)

    这篇文章主要介绍了解决Springboot项目打包后的页面丢失问题(thymeleaf报错),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 详解SpringBoot定制@ResponseBody注解返回的Json格式

    详解SpringBoot定制@ResponseBody注解返回的Json格式

    这篇文章主要介绍了详解SpringBoot定制@ResponseBody注解返回的Json格式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java GUI图形界面开发实现小型计算器流程详解

    Java GUI图形界面开发实现小型计算器流程详解

    本文章向大家介绍Java GUI图形界面开发实现小型计算器,主要包括布局管理器使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • MyBatis代理Dao方式的增删改查的实现小结

    MyBatis代理Dao方式的增删改查的实现小结

    本文主要介绍了MyBatis代理Dao方式的增删改查的实现小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • SpringCloud客户端的负载均衡Ribbon的实现

    SpringCloud客户端的负载均衡Ribbon的实现

    微服务架构,不可避免的存在单个微服务有多个实例,这篇文章主要介绍了SpringCloud客户端的负载均衡Ribbon的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Spring boot 运用策略模式实现避免多次使用if的操作代码

    Spring boot 运用策略模式实现避免多次使用if的操作代码

    这篇文章主要介绍了Spring boot 运用策略模式实现,避免多次使用if,使用策略模式后,新加一种支付策略时,只需要在策略枚举中添加新加的策略信息,外加一个策略类即可,而不再需要添加新的if判断,需要的朋友可以参考下
    2022-08-08

最新评论