锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. 深入理解 Spring 事务管理及其配置

深入理解 Spring 事务管理及其配置

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

目录

1. Spring 事务角色

事务角色的代码示例:

2. 事务相关配置

常用事务属性:

事务配置的代码示例:

3. 事务传播行为

常见的事务传播行为:

事务传播行为的代码示例:

4. 事务配置案例:转账业务与日志记录

完整案例代码:

结论



Spring 事务管理是现代企业级应用中不可或缺的一部分。通过事务管理,开发者可以保证一系列的数据库操作要么全部成功,要么全部回滚,确保数据一致性。在本文中,我们将讨论 Spring 事务管理的角色、配置以及常见的事务传播行为。


1. Spring 事务角色

在 Spring 的事务管理中,存在两个关键角色:事务管理员 和 事务协调员​(33-Spring事务角色)。

  • 事务管理员:指发起事务的一方,通常是在业务层中开启事务的方法。它负责启动整个事务过程。

  • 事务协调员:指参与事务的一方,通常是数据层或业务层中的方法。这些方法会加入由事务管理员开启的事务中,确保操作的原子性。

事务角色的代码示例:


public interface AccountDao {
    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name") String name, @Param("money") Double money);

    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name, @Param("money") Double money);
}

@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;

    @Transactional
    public void transfer(String out, String in, Double money) {
        accountDao.outMoney(out, money);
        accountDao.inMoney(in, money);
    }
}


在这个示例中,AccountService 类是事务管理员,它开启了事务,调用了数据层的两个方法 outMoney() 和 inMoney(),而这些方法则是事务协调员,参与到同一个事务中。


2. 事务相关配置

在 Spring 事务管理中,可以通过注解或 XML 来配置事务。Spring 提供了多种属性来灵活控制事务的行为,例如设置事务是否为只读、是否回滚以及事务传播行为等​(34-Spring事务相关配置) 。

常用事务属性:
  • readOnly :指示事务是否只读,若为 true 则事务仅用于读取操作,优化性能。

  • timeout:设置事务的超时时间,单位为秒。若超过指定时间事务仍未完成,则回滚。

  • rollbackFor :指定哪些异常会导致事务回滚。例如,可以设置为 rollbackFor = {NullPointerException.class},遇到空指针异常时回滚。

  • propagation:设置事务的传播行为,控制事务之间的关系(详细见下文)。

事务配置的代码示例:
@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;

    @Transactional(readOnly = false, timeout = 30, rollbackFor = Exception.class)
    public void transfer(String out, String in, Double money) {
        accountDao.outMoney(out, money);
        accountDao.inMoney(in, money);
    }
}



在这个示例中,transfer() 方法配置了事务为读写事务(非只读),超时时间为 30 秒,并且遇到 Exception 异常时回滚。


3. 事务传播行为

事务传播行为 是指事务协调员对事务管理员所开启事务的处理方式。在 Spring 中,事务传播行为有多种选择,用于定义不同的方法在执行时如何与现有事务互动​(34-Spring事务相关配置) 。

常见的事务传播行为:
  • REQUIRED:默认传播行为。如果存在事务,则加入当前事务;如果不存在事务,则开启一个新的事务。

  • REQUIRES_NEW:无论是否存在事务,都会开启一个新的事务,并暂停当前事务。

  • NESTED:开启一个嵌套事务,允许事务回滚到保存点(save point),而不是完全回滚整个事务。

  • SUPPORTS:如果当前存在事务,则加入事务;如果不存在事务,则以非事务方式执行。

事务传播行为的代码示例:

假设我们要为每次转账操作记录日志,但日志的保存不应依赖于转账事务的成功与否。因此,可以将日志操作配置为 REQUIRES_NEW,确保日志记录总是独立完成。


@Service
public class LogService {
    @Autowired
    private LogDao logDao;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logTransaction(String out, String in, Double money) {
        logDao.saveLog("转账操作:由 " + out + " 到 " + in + " 金额:" + money);
    }
}

@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private LogService logService;

    @Transactional
    public void transfer(String out, String in, Double money) {
        try {
            accountDao.outMoney(out, money);
            accountDao.inMoney(in, money);
        } finally {
            logService.logTransaction(out, in, money);
        }
    }
}

在这个示例中,LogService 使用 REQUIRES_NEW 传播行为,确保日志记录在一个新事务中完成,即使转账操作回滚,日志也不会丢失。


4. 事务配置案例:转账业务与日志记录

一个典型的事务管理案例是银行转账业务。转账需要在 A 账户减钱,B 账户加钱的过程中保持事务的一致性。如果任何一个操作失败,整个事务将回滚。

在加入日志记录功能后,日志应该独立于转账事务进行保存,无论转账是否成功,日志都需要保留。我们可以通过 REQUIRES_NEW 来确保日志记录不受转账事务的影响。

完整案例代码:
@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private LogService logService;

    @Transactional
    public void transfer(String out, String in, Double money) {
        try {
            accountDao.outMoney(out, money);
            accountDao.inMoney(in, money);
        } finally {
            logService.logTransaction(out, in, money);
        }
    }
}

@Service
public class LogService {
    @Autowired
    private LogDao logDao;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logTransaction(String out, String in, Double money) {
        logDao.saveLog("转账操作:由 " + out + " 到 " + in + " 金额:" + money);
    }
}


结论

Spring 的事务管理为我们提供了灵活的配置选项,通过注解或 XML 配置,我们可以控制事务的传播行为、回滚规则和超时时间等属性。在企业级应用中,事务的正确管理可以确保数据的一致性和完整性,同时提高系统的健壮性。


原文链接: https://blog.csdn.net/2302_80084329/article/details/142268144

标签: #JAVA 991 #Spring 84 #软件开发 1171
相关文章

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.