java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring声明式事务(@Transactional)通过AOP实现过程

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

作者:冰糖心书房

Spring的声明式事务通过AOP代理技术实现,扫描标记了@Transactional的类或方法,为目标对象创建代理,方法调用时根据配置开启、提交或回滚事务,从而简化事务管理,提高代码复用性和可维护性

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

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

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

Step 1: 扫描与识别

当 Spring 容器启动时:

Step 2: 创建代理对象

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

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

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

调用被代理对象拦截

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

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

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

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

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

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

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

图解实现原理

+----------------+
| 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 目标对象   |
|  (包含纯粹的业务逻辑)    |
+--------------------------+

总结

关键角色

工作流程

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

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

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

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