Spring 事务 (编程式 & 声明式, Spring 事务传播机制)

简介: Spring 事务 (编程式 & 声明式, Spring 事务传播机制)

事务

事务是一组操作的集合, 是一个不可分割的整体

事务会把所有的操作作为一个整体, 一起向数据库提交或是撤销操作请求. 所以这组操作要么同时成功, 要么同时失败

Spring 中事务的实现

  1. 编程式 (手动写代码操作事务)
  2. 声明式 (通过注解自动开启和提交事务)

编程式事务

  1. 开启事务 / 获取事务, 通过两个 Spring 内置对象获取
  • DataSourceTransactionManager 事务管理器, 用来获取, 提交或回滚事务
  • TransactionDefinition 定义事务的属性, 事务隔离级别, 事务传播机制, 回滚规则 …
  1. 提交事务
  2. 回滚事务

Spring 通过 DataSourceTransactionManager (事务管理器) 和 TransactionDefinition (事务的属性) 来获取事务

@Controller
public class BasicController {
  // 获取事务管理器
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    
  // 定义事务的属性
    @Autowired
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/registry")
    public String registry() {
        // 获取事务 / 开启事务 (transactionStatus 为事务的一个状态, 可以理解为数据库的一个快照)
        TransactionStatus transactionStatus =
                dataSourceTransactionManager.getTransaction(transactionDefinition);

        // 业务逻辑
        User user = new User();
        user.setAge(18);
        user.setName("zrj");
    
    //提交事务
        dataSourceTransactionManager.commit(transactionStatus); 
        
        //回滚事务
//        dataSourceTransactionManager.rollback(transactionStatus); 
        return "ok";
    }
}

声明式事务

使用注解 @Transactional

既是类注解, 也是方法注解

会对注解范围内所有的 public 修饰的方法 生效

@Transactional :

如果方法执行过程中, 出现异常, 且未被捕获, 就进行事务回滚.

如果异常被程序捕获, 则方法对异常无感知, 认为本次执行成功, 就会进行事务提交. 若异常被捕获仍想回滚:

  • 将捕获的异常再次抛出
  • 手动回滚事务 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@RestController
public class PathVariableController {
    @Transactional()
    @RequestMapping("/registry")
    public String registry() {
        User user = new User();
        user.setAge(18);
        user.setName("zrj");
        return "ok";
    }
}

@Transactional 注解的常用属性

  1. rollbackFor : 异常回滚属性. 执行能够触发事务回滚的异常类型, 默认只有 运行时异常和 error 才会触发事务回滚, 其他类型异常并不会触发回滚操作
  1. Isolation : 事务的隔离级别. 默认为 Isolation.DEFAULT
  2. propergation : 事务的传播机制, 默认值为 Propergation.REQUIRED

事务的隔离级别解决 多个事务同时调用一个数据库的问题

事务的传播机制解决 一个事务在多个节点(方法)中传播的问题

Spring 事务的传播机制 – 7种

Propergation.REQUIRED : 如果当前存在事务, 则加入该事务, 如果当前不存在事务, 则创建一个事务

Propergation.SUPPORTS : 如果当前存在事务, 就加入该事务, 如果当前不存在事务,就以非事务的方式继续执行

Propergation.MANDATORY : 强制性, 如果当前存在事务, 就加入该事务, 如果当前不存在事务, 就报错

Propergation.REQUIED_NEW : 创建一个新事务, 如果当前存在事务, 就将当前事务挂起

Propergation.NOT_SUPPORTED :非事务的方式运行, 如果当前存在事务, 就将当前事务挂起

Propergation.NEVER : 以非事务的方式运行, 如果当前存在事务, 就抛出异常

Propergation.NESTED : 如果当前存在事务, 则创建一个事务作为当前事务的嵌套事务/子事务来运行, 如果没有事务, 则创建一个事务


NESTED & REQUIRED

  • 如果事务全部执行成功, 二者的结果是一样的
  • 如果事务部分执行成功, 部分执行失败, REQUIRED 加入事务 会导致整个事务 全部回滚, NESTED 嵌套事务 可以实现 部分回滚 (savepoint 机制)

目录
相关文章
|
23天前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
24天前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
258 0
|
2月前
|
Java API 开发者
Spring 控制反转与依赖注入:从玄学编程到科学管理
在传统开发中,手动`new`对象导致紧耦合、难以维护和测试。控制反转(IoC)将对象创建交给框架,实现解耦。Spring通过IOC容器自动管理对象生命周期,开发者只需声明依赖,无需关心创建细节。依赖注入(DI)是IoC的具体实现方式,支持构造器、Setter和字段注入。构造器注入推荐使用,保证依赖不可变且易于测试。对于多个同类型Bean,可用`@Qualifier`或`@Primary`解决冲突。此外,Spring还支持依赖查找(DL),开发者主动从容器获取Bean,适用于动态场景,但侵入性强。掌握IoC与DI,有助于构建灵活、可维护的Spring应用。
|
2月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
2月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
|
7月前
|
Java Spring
Spring中事务失效的场景
因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时, 那么这个注解才会⽣效 , 如果使用的是被代理对象调用, 那么@Transactional会失效 同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效 如果在业务中对异常进行了捕获处理 , 出现异常后Spring框架无法感知到异常, @Transactional也会失效
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——常见问题总结
本文总结了Spring Boot中使用事务的常见问题,虽然通过`@Transactional`注解可以轻松实现事务管理,但在实际项目中仍有许多潜在坑点。文章详细分析了三个典型问题:1) 异常未被捕获导致事务未回滚,需明确指定`rollbackFor`属性;2) 异常被try-catch“吃掉”,应避免在事务方法中直接处理异常;3) 事务范围与锁范围不一致引发并发问题,建议调整锁策略以覆盖事务范围。这些问题看似简单,但一旦发生,排查难度较大,因此开发时需格外留意。最后,文章提供了课程源代码下载地址,供读者实践参考。
142 0
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
934 0
|
7月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——事务相关
本文介绍Spring Boot事务配置管理,阐述事务在企业应用开发中的重要性。事务确保数据操作可靠,任一异常均可回滚至初始状态,如转账、购票等场景需全流程执行成功才算完成。同时,事务管理在Spring Boot的service层广泛应用,但根据实际需求也可能存在无需事务的情况,例如独立数据插入操作。
153 0