Spring编程式事务和声明式事务

在 Spring 中,事务管理主要有两种方式:编程式事务声明式事务。它们的核心目标都是保证数据操作的原子性、一致性、隔离性和持久性(ACID),但实现方式和适用场景有显著区别。

编程式事务

编程式事务 是通过手动编写代码来控制事务的开启、提交、回滚等操作,开发者需要显式地管理事务的生命周期,核心类是 TransactionTemplate,它依赖 PlatformTransactionManager(事务管理器)来完成实际的事务操作。

java 复制代码
@Service
public class UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private PlatformTransactionManager transactionManager;

    public void transferMoney(Long fromId, Long toId, int amount) {
        // 1. 定义事务属性(传播行为、隔离级别等)
        TransactionDefinition definition = new DefaultTransactionDefinition() {{
            setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
            setTimeout(30); // 超时时间 30 秒
        }};

        // 2. 开启事务
        TransactionStatus status = transactionManager.getTransaction(definition);

        try {
            // 执行数据库操作(扣钱)
            jdbcTemplate.update("UPDATE user SET balance = balance - ? WHERE id = ?", amount, fromId);
            // 执行数据库操作(加钱)
            jdbcTemplate.update("UPDATE user SET balance = balance + ? WHERE id = ?", amount, toId);

            // 3. 无异常则提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            // 4. 有异常则回滚事务
            transactionManager.rollback(status);
            throw new RuntimeException("转账失败", e);
        }
    }
}

声明式事务

声明式事务 是基于 AOP(面向切面编程),通过 @Transactional 注解或 XML 配置定义事务属性,在运行时动态生成代理对象,拦截目标方法并管理事务。需在 Spring 配置类中定义事务管理器(如 @EnableTransactionManagement 开启注解驱动,并注册 DataSourceTransactionManager)。

自调用失效 :同一类中,一个无事务方法调用另一个有事务的方法时,事务不会生效(因 Spring 事务基于 AOP 代理,自调用不会经过代理对象)解决:注入自身 Bean 或通过 AopContext.currentProxy() 获取代理对象调用。

@Transactional 可标注在 方法 上:

  • 标注在类上:表示该类中所有公共方法(public)都默认应用该事务配置。
  • 标注在方法上:表示该方法单独使用事务配置(方法级配置会覆盖类级配置)。

事务管理器(多数据源场景下需指定):value/transactionManager

事务传播行为(propagation):propagation = Propagation.REQUIRED(默认)如果当前已经存在事务 (即调用该方法的外层方法已有事务),则加入当前事务 ,方法与外层事务共用一个事务(同成功、同回滚)。如果当前没有事务 (外层方法无事务),则创建一个新的事务,方法在新事务中执行。

事务隔离级别(isolation):DEFAULT:使用数据库默认隔离级别(如 MySQL 默认为 REPEATABLE_READ)。

只读事务readOnly:默认false

事务超时时间time:(秒):默认-1无超时时间,超时后自动回滚。

回滚规则:默认情况下,事务仅在抛出 未捕获的 RuntimeExceptionError 时回滚; checked 异常(如 IOException)不会触发回滚,可过 rollbackFornoRollbackFor 自定义

PlatformTransactionManager

两种方式的底层都依赖Spring 框架的 PlatformTransactionManager 接口实现事务的具体操作(如提交、回滚),只是编程式需要手动触发,而声明式由 Spring 自动触发。

PlatformTransactionManager 负责管理事务的生命周期,包括:

  • 开启事务(getTransaction(...)
  • 提交事务(commit(...)
  • 回滚事务(rollback(...)

它是一个**抽象接口,**具体的事务管理逻辑由其实现类根据不同的资源类型(如 JDBC、JPA、Hibernate 等)实现。

实现类 适用场景 依赖资源
DataSourceTransactionManager 管理 JDBC 事务(最常用) javax.sql.DataSource
JpaTransactionManager 管理 JPA 事务 JPA EntityManagerFactory
HibernateTransactionManager 管理 Hibernate 事务(旧版本 Hibernate) Hibernate SessionFactory
JtaTransactionManager 管理分布式事务(跨多个资源,如多数据库) JTA 环境(如 Java EE 容器)
RabbitTransactionManager 管理 RabbitMQ 消息队列事务 RabbitMQ ConnectionFactory
相关推荐
若鱼19197 分钟前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
倒流时光三十年10 分钟前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
觉醒大王16 分钟前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法
努力学编程呀(๑•ี_เ•ี๑)24 分钟前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
码农小卡拉34 分钟前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
怣5038 分钟前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
向上的车轮41 分钟前
为什么.NET(C#)转 Java 开发时常常在“吐槽”Java:checked exception
java·c#·.net
Dragon Wu42 分钟前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
跳动的梦想家h1 小时前
环境配置 + AI 提效双管齐下
java·vue.js·spring
坚持就完事了1 小时前
Java中的集合
java·开发语言