锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. Spring事务类型及传播行为实战指南

Spring事务类型及传播行为实战指南

0
  • JAVA
  • 发布于 2024-09-29
  • 14 次阅读
黄健
黄健

Spring事务类型及传播行为实战指南

在Spring框架中,事务管理是确保数据一致性和完整性的关键部分。通过合理的事务管理,可以确保在数据库操作过程中的原子性、一致性、隔离性和持久性。本文将从Spring事务的基础概念、事务类型、传播行为以及实战案例等方面进行详细讲解。

一、Spring事务基础

1.1 事务概述

事务是一组数据库操作的逻辑单元,具有原子性、一致性、隔离性和持久性(ACID)四个特性。在Spring中,事务管理提供了一种可靠且灵活的方式来管理这些操作,确保数据的一致性和完整性。

  • 原子性(Atomicity):事务中的所有操作要么全部成功执行并提交,要么全部失败并回滚,保持数据的一致性。
  • 一致性(Consistency):事务的执行过程中,数据库从一个一致的状态转变为另一个一致的状态,不会破坏数据的完整性。
  • 隔离性(Isolation):多个并发事务之间应该相互隔离,每个事务的操作应该看起来像是在独立执行,避免数据冲突和不一致性。
  • 持久性(Durability):一旦事务提交,其对数据库的修改应该是永久性的,即使在系统故障或重启后也能够恢复。

1.2 事务管理器

事务管理器是Spring提供的一个接口,用于管理事务的开始、提交和回滚操作。它与底层的数据库或持久化框架进行交互,并确保事务的正确执行。Spring提供了多种事务管理器,如DataSourceTransactionManager、JpaTransactionManager、HibernateTransactionManager和JtaTransactionManager等,以适应不同的应用场景和开发需求。

1.3 事务定义和注解

事务定义(Transaction Definition)定义了事务的属性,如隔离级别、传播行为、超时设置等。在Spring中,事务定义可以通过编程方式或声明式方式来定义。声明式事务定义是通过在方法或类级别上使用注解或XML配置来定义事务的属性。Spring提供了@Transactional注解,用于在方法级别上定义事务的属性。

二、事务类型

Spring支持两种主要的事务管理方式:编程式事务管理和声明式事务管理。

2.1 编程式事务管理

编程式事务管理通过编写代码来显式地管理事务的开始、提交和回滚。这种方式提供了更高的灵活性,但代码量较大,容易出错。Spring提供了TransactionTemplate等工具类来简化编程式事务管理的实现。

2.2 声明式事务管理

声明式事务管理通过注解或XML配置来定义事务的边界和属性,无需在代码中显式地编写事务管理代码。这种方式使事务管理与业务逻辑分离,简化了代码,提高了可维护性。@Transactional注解是声明式事务管理中最常用的方式。

三、事务传播行为

事务传播行为(propagation behavior)指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行。Spring在TransactionDefinition接口中规定了7种类型的事务传播行为。

3.1 REQUIRED

  • 行为描述:如果当前存在事务,则加入该事务中执行;如果当前没有事务,则创建一个新的事务执行。这是Spring默认的传播行为。
  • 应用场景:适用于大多数需要事务支持的方法,特别是当方法可能被其他事务方法调用时。

3.2 REQUIRES_NEW

  • 行为描述:总是创建一个新的事务,并挂起当前事务(如果存在)。在新的事务中执行方法,不受外部事务的影响。
  • 应用场景:适用于需要确保方法执行完全独立于外部事务的场景,例如,在嵌套事务中需要完全隔离的操作。

3.3 SUPPORTS

  • 行为描述:如果当前存在事务,就加入该事务;如果当前不存在事务,就以非事务方式执行。
  • 应用场景:适用于那些对事务没有强制要求的方法,但在有事务存在时可以参与。

3.4 NOT_SUPPORTED

  • 行为描述:如果当前存在事务,就把当前事务挂起。以非事务方式执行方法。
  • 应用场景:适用于那些不需要事务支持的操作,例如,读取数据但不修改数据的操作。

3.5 MANDATORY

  • 行为描述:如果当前存在事务,就加入该事务;如果当前不存在事务,就抛出异常。
  • 应用场景:适用于那些必须在事务中执行的方法,确保操作的原子性和一致性。

3.6 NEVER

  • 行为描述:以非事务方式执行方法,如果当前存在事务,则抛出异常。
  • 应用场景:适用于那些绝对不能在事务中执行的操作,确保操作的独立性。

3.7 NESTED

  • 行为描述:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,就创建一个新事务。
  • 应用场景:适用于需要在当前事务内部执行一个具有部分回滚能力的子事务的场景。

四、实战案例

4.1 场景描述

假设有一个电商系统,其中包括用户购买商品的操作。购买操作涉及到多个数据库操作,如库存减少、用户余额减少等,这些操作需要在一个事务中完成,以确保数据的一致性。

4.2 实现步骤

  1. 定义服务层接口和实现

    定义一个BookShopService接口和它的实现类BookShopServiceImpl,用于处理购买商品的业务逻辑。

    public interface BookShopService {
    
       void purchase(String username, String isbn);
    }
    
    @Service
    @Transactional(propagation = Propagation.REQUIRED)
    public class BookShopServiceImpl implements BookShopService {
    
       @Autowired
       private BookShopDao bookShopDao;
    
       @Override
       public void purchase(String username, String isbn) {
    
           // 1. 获取书的单价
           int price = bookShopDao.findBookPriceByIsbn(isbn);
           // 2. 更新书的库存
           bookShopDao.updateBookStock(isbn);
           // 3. 更新用户的余额
           bookShopDao.updateUserAccount(username, price);
       }
    }
    

    注意,在BookShopServiceImpl类上使用了@Transactional注解,并指定了传播行为为REQUIRED。这意味着如果当前存在事务,则购买操作将加入该事务;如果当前没有事务,则创建一个新的事务。

  2. 调用服务层方法

    在需要购买商品的地方,直接调用BookShopService的purchase方法即可。

    @Autowired
    private BookShopService bookShopService;
    
    public void checkout(String username, List<String> isbns) {
    
       for (String isbn : isbns) {
    
           bookShopService.purchase(username, isbn);
       }
    }
    

    由于purchase方法已经通过@Transactional注解声明了事务,因此在checkout方法中调用purchase方法时,所有的购买操作将在一个事务中完成,确保数据的一致性。

4.3 隔离级别和错误处理

在实际应用中,还需要根据业务需求设置合适的隔离级别,并在发生错误时进行适当的错误处理和事务回滚。

  • 设置隔离级别 :可以通过@Transactional注解的isolation属性来设置隔离级别。
  • 错误处理 :在purchase方法中,如果发生异常,Spring将自动回滚事务,确保数据的一致性。

五、总结

Spring事务管理提供了可靠且灵活的方式来管理数据库操作中的事务,确保数据的一致性和完整性。通过合理使用事务类型和传播行为,可以灵活地控制事务的边界和行为,满足各种业务需求。在实际开发中,应根据具体业务场景选择合适的事务管理方式,并合理设置事务属性和隔离级别,以确保系统的稳定性和可靠性。

原文链接: https://blog.csdn.net/hai40587/article/details/142483723

标签: #Spring 84 #JAVA 991
相关文章

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

SpringBoot整合异步任务执行 2024-10-08 11:24

同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢,影响用 户体验 异步任务: 异步任务是在多线程中同时执行,多个任务可以并发执行,同时处理多个请求,响应快,资源

springboot kafka多数据源,通过配置动态加载发送者和消费者 2024-10-08 11:24

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需要对架构做一定的设计了。 准备test kafka本身非常容易上手,如果我们需要单元测试,引入ja

SpringBoot 集成 Redis 2024-10-08 11:24

一:SpringBoot 集成 Redis ①Redis是一个 NoSQL(not only)数据库, 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器;常用的数据类型: string , hash ,set ,zset , list ③通过Redis客户端可以使用多种语

SpringBoot整合QQ邮箱 2024-10-08 11:24

SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件…. 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,如果当前账号未开启的话自己手动开启。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.