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注解即可。

相关推荐
A阳俊yi2 小时前
Spring——编程式事务
数据库·sql·spring
我要精通C++2 小时前
lua虚拟机的垃圾回收机制
java·开发语言
22jimmy2 小时前
MyBatis动态sql
java·开发语言·mybatis
编程充电站pro2 小时前
SQL 多表查询常用语法速查:INNER JOIN / LEFT JOIN / RIGHT JOIN
数据库·sql
杨云龙UP3 小时前
SQL Server数据库事务日志问题的诊断与解法(从膨胀到瘦身)
运维·数据库·sql·sqlserver·serverless
那我掉的头发算什么3 小时前
【数据结构】双向链表
java·开发语言·数据结构·链表·intellij-idea·idea
半桔3 小时前
【STL源码剖析】从源码看 list:从迭代器到算法
java·数据结构·c++·算法·stl·list
666HZ6663 小时前
Java Stream流
java·开发语言
学编程的小鬼3 小时前
全局异常处理器
java·spring boot