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
相关推荐
0xDevNull4 小时前
MySQL数据冷热分离详解
后端·mysql
一定要AK4 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao4 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao4 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
迷藏4944 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源
阿里小阿希5 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神5 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle