Spring——声明式事务

目录

声明式事务的实现方式

XML配置

配置类配置

混合配置


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

特性 编程式事务 声明式事务
代码侵入性 强,事务代码与业务代码混合 弱,通过配置或注解,代码几乎无侵入
控制粒度 细粒度,可以精确控制事务边界 粗粒度,通常作用于方法级别
灵活性 高,可以根据条件动态控制事务 相对较低,配置固定,但可通过条件表达式等增强
可维护性 低,事务代码分散在业务代码中 高,事务配置集中管理
实现方式 编写代码,使用PlatformTransactionManagerTransactionTemplate 使用注解(如@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注解即可。

相关推荐
ajassi20004 分钟前
开源 Linux 服务器与中间件(八)数据库--MariaDB
服务器·数据库·开源
blammmp5 分钟前
RabbitMQ :概述,Web界面介绍,快速上手,工作模式
java·分布式·rabbitmq
何中应5 分钟前
如何截取PDF内容为图片
java·开发语言·后端·pdf
华仔啊38 分钟前
这20条SQL优化方案,让你的数据库查询速度提升10倍
数据库·后端·mysql
赵庆明老师41 分钟前
C# 结合Redis Cache 访问MySQL数据库
数据库·redis·c#
IvorySQL1 小时前
为IvorySQL增添PACKAGE语法帮助
数据库·postgresql
哈皮Superman1 小时前
【Research】MagicFuzzer: Scalable deadlock detection for large-scale applications
java·开发语言·数据库
自由会客室1 小时前
Ubuntu 24.04上安装MySQL 8.0
数据库·mysql
I'm Jie2 小时前
(二)Gradle 依赖仓库及安全凭证配置
java·spring boot·spring·gradle·maven
牢七2 小时前
CATWIFI
java