java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring声明式事务管理

Spring声明式事务管理从原理到实战示例

作者:lang20150928

本文主要介绍了Spring声明式事务管理的概念、实现原理、配置方法、异常回滚机制、不同类的事务配置以及响应式事务的支持,声明式事务通过配置或注解简化了事务管理,使用AOP实现,支持多种传播行为和隔离级别,感兴趣的朋友跟随小编一起看看吧

🌟 一、什么是声明式事务管理?

✅ 简单说:

你不用在代码里手动写 beginTransaction()commit()rollback(),而是通过配置或注解来告诉 Spring:“这个方法需要事务”,Spring 自动帮你管理事务的开始、提交或回滚。

🔁 对比:编程式 vs 声明式

类型特点代码侵入性
编程式事务手动控制事务(如使用 TransactionTemplate高(代码里到处是事务逻辑)
声明式事务用配置或注解声明事务行为低(业务代码干净)

📌 Spring 推荐使用 声明式事务,因为它更符合“轻量级容器”的理念 —— 业务代码不依赖事务框架。

🧠 二、声明式事务是如何实现的?(核心原理)

Spring 的声明式事务是基于 AOP(面向切面编程) 实现的。

🔍 工作流程如下:

  1. 你有一个服务类,比如 DefaultFooService
  2. 你在配置中声明了哪些方法需要事务(通过 <tx:advice>@Transactional)。
  3. Spring 在启动时,会为这个类创建一个 代理对象(Proxy)
  4. 当你调用 fooService.insertFoo(...) 时,实际上是调用了代理对象的方法。
  5. 代理对象在方法执行前开启事务,执行后根据结果决定提交或回滚。
你调用:   fooService.insertFoo()
        ↓
实际执行:  Proxy → 开启事务 → 调用真实方法 → 成功则提交,异常则回滚

🛠️ 关键组件:

📝 三、如何配置声明式事务?(XML 配置方式)

文档中的例子使用 XML 配置,虽然现在更多用注解,但理解 XML 有助于理解底层机制。

示例配置解析:

<!-- 定义数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> ... </bean>
<!-- 定义事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 定义事务通知(规则) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true"/>  <!-- 所有get开头的方法:只读事务 -->
        <tx:method name="*" />                     <!-- 其他方法:默认事务(读写) -->
    </tx:attributes>
</tx:advice>
<!-- 将事务通知应用到指定的切点 -->
<aop:config>
    <!-- 切点:匹配 FooService 接口的所有方法 -->
    <aop:pointcut id="fooServiceOperation" 
                  expression="execution(* x.y.service.FooService.*(..))"/>
    <!-- 绑定通知和切点 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
</aop:config>

📌 关键点:

💡 四、事务回滚机制(Rollback Rules)

这是 Spring 事务的一大亮点:你可以精确控制哪些异常触发回滚。

默认规则:

⚠️ 这与 EJB CMT 不同!EJB 中检查型异常也不回滚,但 Spring 允许你自定义。

自定义回滚规则:

1. 某个检查型异常也要回滚:

<tx:method name="updateStock" rollback-for="NoProductInStockException"/>

2. 某个运行时异常不要回滚:

<tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>

3. 多规则优先级:

<tx:method name="*" 
           rollback-for="Throwable" 
           no-rollback-for="InstrumentNotFoundException"/>

✅ 所有异常都回滚,除了 InstrumentNotFoundException

🔄 五、响应式事务(Reactive Transaction Management)

Spring 5+ 支持响应式编程(如 WebFlux),事务也支持响应式。

关键区别:

特性传统(Imperative)响应式(Reactive)
返回类型Foo, voidMono<Foo>, Flux<Foo>
事务管理器PlatformTransactionManagerReactiveTransactionManager
事务传播基于 ThreadLocal基于 Reactor Context
事务触发方法调用立即开始返回的 Publisher 被订阅时才开始

📌 响应式事务是“惰性的”:调用方法不立即开启事务,而是等到 .subscribe() 时才开始。

🛠️ 六、不同 Bean 使用不同事务配置

你可以为不同的服务类设置不同的事务规则。

示例:

<aop:pointcut id="defaultServiceOperation" 
              expression="execution(* x.y.service.*Service.*(..))"/>
<aop:pointcut id="noTxServiceOperation" 
              expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>
<aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>
<aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>

📌 这很实用,比如 DDL 操作(建表、删表)通常不应在事务中运行。

📋 七、<tx:method>的所有配置项总结

属性是否必需默认值说明
name✅ 是-方法名(支持 * 通配符)
propagationREQUIRED传播行为(如 REQUIRED, REQUIRES_NEW, NEVER 等)
isolationDEFAULT隔离级别(如 READ_COMMITTED
timeout-1(无超时)超时时间(秒)
read-onlyfalse是否只读事务
rollback-for-哪些异常触发回滚(可写多个,逗号分隔)
no-rollback-for-哪些异常触发回滚

🧩 八、重要注意事项

@Service
public class FooService {
    @Transactional(readOnly = true)
    public Foo getFoo(String name) { ... }
    @Transactional(rollbackFor = MyException.class)
    public void updateFoo(Foo foo) { ... }
}

需要启用:@EnableTransactionManagement

✅ 总结:如何理解这段内容?

问题回答
声明式事务是什么?用配置或注解声明事务,无需手动控制。
怎么实现的?基于 AOP,Spring 创建代理对象,在方法前后自动加事务逻辑。
怎么配置?<tx:advice> 定义规则,用 <aop:config> 应用到目标方法。
异常怎么回滚?默认运行时异常回滚,可通过 rollback-for 自定义。
不同类不同配置?可以,定义多个 <tx:advice><aop:advisor>
响应式支持吗?支持,基于 ReactiveTransactionManager 和 Reactor 上下文。

📚 建议学习路径

  1. 先理解 AOP 基本概念(代理、切点、通知)
  2. 动手写一个 XML 配置的声明式事务例子
  3. 改造成 @Transactional 注解方式
  4. 尝试 自定义回滚规则
  5. 了解 事务传播行为(如 REQUIRED, REQUIRES_NEW
  6. (进阶)学习 响应式事务分布式事务

如果你希望,我可以:

欢迎继续提问!

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

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