Spring——声明式事务

目录

声明式事务的实现方式

XML配置

配置类配置

混合配置


Spring声明式基于AOP 实现,是通过配置注解 或xml来管理事务,而不需要在业务代码中像编程式事务那样管理代码。

特性 编程式事务 声明式事务
代码侵入性 强,事务代码与业务代码混合 弱,通过配置或注解,代码几乎无侵入
控制粒度 细粒度,可以精确控制事务边界 粗粒度,通常作用于方法级别
灵活性 高,可以根据条件动态控制事务 相对较低,配置固定,但可通过条件表达式等增强
可维护性 低,事务代码分散在业务代码中 高,事务配置集中管理
实现方式 编写代码,使用PlatformTransactionManager或TransactionTemplate 使用注解(如@Transactional)或XML配置
底层技术 直接使用事务API 基于Spring AOP和代理机制

声明式事务的实现方式

声明式事务可以通过XML或注解配置,也可以混合使用。

XML配置

xml配置声明式有三个步骤:

  1. 配置事务管理器
  2. 配置事务通知
  3. 配置AOP

配置事务管理器:

XML 复制代码
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>

配置事务通知:

配置说明:

  1. 事务通知(tx:advice)

    • id="txAdvice":事务通知的唯一标识
    • transaction-manager="transactionManager":关联前面定义的事务管理器
  2. 事务属性(tx:attributes) 通过<tx:method>定义不同方法的事务规则,支持通配符匹配方法名:

    • name:方法名匹配规则(如save*匹配所有以 save 开头的方法)
    • propagation:事务传播行为(核心属性)
      • REQUIRED:默认值,当前无事务则新建,有则加入
      • REQUIRES_NEW:强制新建事务,暂停当前事务(若存在)
      • SUPPORTS:支持事务,无事务则非事务执行
    • isolation:事务隔离级别(默认DEFAULT,使用数据库默认)
    • read-only:是否只读(查询方法设为true,优化性能)
    • rollback-for:指定需要回滚的异常(默认仅回滚 RuntimeException)
    • timeout:事务超时时间(-1 表示无限制)
XML 复制代码
    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
        <tx:attributes>
            <tx:method name="add*"/>
            <tx:method name="update*"/>
            <tx:method name="delete*"/>
            <tx:method name="insert*"/>
            <tx:method name="transfer*"/>
        </tx:attributes>
    </tx:advice>

配置AOP:

XML 复制代码
    <aop:config>
        <aop:pointcut expression="execution(* com.cc.service.*.*(..))" id="pc"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    </aop:config>

然后编写方法,注意方法名要和配置的方法名对应:

java 复制代码
public void update2(){
        userDao.updateUsernameById(1,"ng");
        int i = 1/0;
    }

这样调用该方法,抛异常时就会自动回滚。

配置类配置

首先写一个java配置类来代替spring的配置文件,里面包含了定义事务管理器和mybatis配置:

java 复制代码
@Configuration
@ComponentScan("com.cc")
@EnableTransactionManagement
@MapperScan("com.cc.dao")
public class JavaConfig {
    @Bean
    DataSource dataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/shop-user");
        ds.setUsername("root");
        ds.setPassword("123456");
        return ds;
    }
    
    @Bean
    PlatformTransactionManager transactionManager(){
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        return sessionFactory.getObject();
    }

}

接着在业务方法上面加上注解@Transactional,

复制代码
@Transactional
public void tr(){
    userDao.updateUsernameById(1,"ng1n");
    int i = 1/0;
}

然后用一个main方法区调用,发现事务自动回滚:

java 复制代码
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
        UserService2 bean = context.getBean(UserService2.class);
        bean.tr();
    }

混合配置

混合配置使用xml+注解的方式,无需使用配置类

XML中的配置:

复制代码
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/shop-user"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</bean>

<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
    <property name="dataSource" ref="dataSource"></property>
</bean>

<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

\<!-- 开启注解式事务支持--\>
<tx:annotation-driven/>

后面直接使用@Transactional注解即可。

相关推荐
KaiwuDB16 分钟前
KaiwuDB 运维实战04:DRBD + KaiwuDB——物联网场景下的低成本数据库高可用方案
运维·数据库·物联网·时序数据库·kaiwudb·aiot·多模数据库
夜雪一千2 小时前
MySQL外键彻底入门:是什么、怎么用、什么时候不该用
数据库·mysql
蜗牛互联网2 小时前
WSL Containers GA:本地AI容器的生命周期、网络与治理验收
java·网络·人工智能·后端
qq_334466862 小时前
删除SSMS的历史登录记录
数据库·sql
zl_dfq2 小时前
Redis 之 【常见面试题总结】(从数据类型到高可用、缓存一致性全解析)
数据库·redis
龙亘川2 小时前
铭记英烈守初心,数字强基促服务:亘川智城退役军人服务系统的实践与价值
java·数据库·人工智能
OxYGC3 小时前
[AI工程] Spring AI 第廿一篇:存量 REST 接口的 MCP 化改造实录——工具从哪条路径注册、参数描述怎么写、身份怎么过去
java·人工智能·spring
Zhou1411363 小时前
SpringBoot_02_自动配置原理
java·spring boot·后端
FYKJ_20103 小时前
SSM校园失物招领系统41452-计算机课程设计、毕业设计
java·vue.js·spring boot·python·mysql·typescript·spark
kv1103 小时前
Android studio国内开发有关
java·数据库·android studio