Spring框架事务配置详解:<tx:advice/>标签的使用指南

Spring框架事务配置详解:tx:advice/标签的使用指南

spring-framework spring-projects/spring-framework: 一个基于 Java 的开源应用程序框架,用于构建企业级 Java 应用程序。适合用于构建各种企业级 Java 应用程序,可以实现高效的服务和管理。 spring-framework 项目地址: https://gitcode.com/gh_mirrors/sp/spring-framework

前言

在Spring框架中,声明式事务管理是开发企业级应用时不可或缺的功能。通过使用<tx:advice/>标签,开发者可以以声明式的方式配置事务属性,而无需在业务代码中编写繁琐的事务管理代码。本文将深入解析<tx:advice/>标签的各项配置属性,帮助开发者掌握Spring声明式事务的核心配置技巧。

tx:advice/默认配置

Spring框架为<tx:advice/>提供了一套合理的默认配置,这些默认值适用于大多数常见场景:

  1. 传播行为(Propagation): 默认为REQUIRED,表示如果当前存在事务,则加入该事务;如果没有,则创建一个新事务
  2. 隔离级别(Isolation): 默认为DEFAULT,表示使用底层数据库的默认隔离级别
  3. 读写属性: 默认为读写事务
  4. 超时设置: 默认使用底层事务系统的超时设置,如果不支持超时则为无限制
  5. 回滚规则: 默认情况下,运行时异常(RuntimeException)会触发回滚,而受检异常(checked Exception)不会触发回滚

tx:method/属性详解

<tx:advice/>的核心配置是通过嵌套的<tx:method/>标签完成的,每个<tx:method/>可以针对特定方法或方法模式配置事务属性。

1. name属性(必需)

  • 作用:指定要应用事务属性的方法名称
  • 特点
    • 支持通配符(*)匹配,如get*匹配所有以get开头的方法
    • 可以精确指定方法名,如findById
    • 支持多个方法模式,用逗号分隔

2. propagation属性(可选)

  • 默认值:REQUIRED
  • 可选值
    • REQUIRED:支持当前事务,不存在则新建
    • SUPPORTS:支持当前事务,不存在则以非事务方式执行
    • MANDATORY:必须存在当前事务,否则抛出异常
    • REQUIRES_NEW:新建事务,挂起当前事务
    • NOT_SUPPORTED:以非事务方式执行,挂起当前事务
    • NEVER:以非事务方式执行,存在事务则抛出异常
    • NESTED:如果当前存在事务,则在嵌套事务内执行

3. isolation属性(可选)

  • 默认值:DEFAULT
  • 适用场景:仅当传播行为为REQUIRED或REQUIRES_NEW时有效
  • 可选值
    • DEFAULT:使用底层数据库默认隔离级别
    • READ_UNCOMMITTED:读未提交
    • READ_COMMITTED:读已提交
    • REPEATABLE_READ:可重复读
    • SERIALIZABLE:串行化

4. timeout属性(可选)

  • 默认值:-1(表示使用底层事务系统默认超时)
  • 单位:秒
  • 适用场景:仅当传播行为为REQUIRED或REQUIRES_NEW时有效
  • 注意:某些事务管理器可能不支持超时设置

5. read-only属性(可选)

  • 默认值:false
  • 适用场景:仅当传播行为为REQUIRED或REQUIRES_NEW时有效
  • 作用
    • 设置为true时,表示事务为只读,可优化某些数据库操作
    • 设置为false时,表示事务可读写

6. rollback-for属性(可选)

  • 作用:指定哪些异常类型应触发回滚
  • 格式:全限定类名的逗号分隔列表
  • 示例com.example.MyBusinessException,ServletException
  • 注意:会覆盖默认的只对RuntimeException回滚的行为

7. no-rollback-for属性(可选)

  • 作用:指定哪些异常类型不应触发回滚
  • 格式:全限定类名的逗号分隔列表
  • 示例com.example.MyNonCriticalException

最佳实践建议

  1. 合理使用传播行为:根据业务逻辑需求选择合适的传播行为,例如对于日志记录等非核心操作可使用REQUIRES_NEW

  2. 隔离级别选择:在保证数据一致性的前提下,尽量选择较低的隔离级别以提高性能

  3. 超时设置:对于可能长时间运行的操作,应设置合理的超时时间,避免长时间占用数据库连接

  4. 只读事务优化:对于查询操作,明确设置read-only="true"可帮助数据库优化执行计划

  5. 异常处理:根据业务需求精确控制哪些异常应触发回滚,特别是对于受检异常的处理

配置示例

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" timeout="30"/>
        <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
        <tx:method name="delete*" propagation="REQUIRES_NEW"/>
        <tx:method name="get*" read-only="true" timeout="10"/>
        <tx:method name="find*" read-only="true"/>
    </tx:attributes>
</tx:advice>

通过本文的详细解析,开发者应该能够全面掌握Spring框架中<tx:advice/>标签的使用方法,从而在实际项目中灵活配置事务属性,构建健壮的事务管理策略。

spring-framework spring-projects/spring-framework: 一个基于 Java 的开源应用程序框架,用于构建企业级 Java 应用程序。适合用于构建各种企业级 Java 应用程序,可以实现高效的服务和管理。 spring-framework 项目地址: https://gitcode.com/gh_mirrors/sp/spring-framework

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--开启Spring的注解--> <context:annotation-config/> <!--Spring的注解扫描包路径--> <context:component-scan base-package="com.example"/> <!--加载数据源连接池--> <bean name="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1/apsfc?serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!--创建SqlSessionFactory对象--> <bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--注入数据源连接池--> <property name="dataSource" ref="druidDataSource"/> <!--注入Mybatis的主配置文件--> <property name="configLocation" value="classpath:sqlMapConfig.xml"/> <!--配置DAO的映射文件扫描路径--> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!--加载DAO接口扫描--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--将SqlSessionFactory对象进行注入--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--配置DAO接口的扫描基础路径--> <property name="basePackage" value="com.example.meal_ordering_system.dao.**"/> </bean> <!--加载事务管理器--> <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--加载数据源连接池--> <property name="dataSource" ref="druidDataSource"/> </bean> <!--配置事务增强通知--> <!--transaction-manager加载指定的事务管理器--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--事务规则列表--> <tx:attributes> <!--propagation定义动作的规则--> <!--REQUIRED阻断操作--> <!--NOT_SUPPORTED非阻断操作--> <!--对新增数据操作的规则定义--> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <!--对修改数据操作的规则定义--> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="edit*" propagation="REQUIRED"/> <!--对删除数据操作的规则定义--> <tx:method name="delete*" propagation="REQUIRED"/> <!--对查询数据操作的规则定义--> <tx:method name="get*" propagation="NOT_SUPPORTED"/> <tx:method name="select*" propagation="NOT_SUPPORTED"/> <tx:method name="query*" propagation="NOT_SUPPORTED"/> </tx:attributes> </tx:advice> <!--托管通知工具类--> <bean name="advice" class="com.example.meal_ordering_system.util.AdviceUtil"/> <!--切面的配置--> <aop:config> <!--切面定义在Service层--> <aop:pointcut id="pointCut" expression="execution(* com.example.meal_ordering_system.service..*(..))"/> <!--事务增强通知与切面进行绑定--> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/> <!--切面织入--> <aop:aspect ref="advice"> <aop:before method="before" pointcut-ref="pointCut"/> <aop:after method="after" pointcut-ref="pointCut"/> <aop:around method="around" pointcut-ref="pointCut"/> <aop:after-throwing method="exception" pointcut-ref="pointCut"/> </aop:aspect> </aop:config> </beans>
最新发布
05-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江涛奎Stranger

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值