Spring事物的传播特性详解

yizhihongxing

Spring 事务的传播特性详解

在开发中,我们常常需要对数据进行事务管理,保证多条SQL语句的原子性,不仅加强了应用程序的稳定性,而且能够提高并发性,减少资源的消耗。Spring事务是优秀的事务管理框架之一,其中最重要的概念就是事务的传播特性。

什么是事务的传播特性

传播特性是指事务的一个属性,当一个事务方法调用另一个事务方法时,称被调用的事务方法为 被嵌套的事务方法。在被嵌套的事务方法中,我们可以指定这个事务方法是否应该与外部事务共享,以及事务的传播行为。

Spring事务传播特性分类

Spring事务传播特性一共有7种,在不同的情况下,可以根据传播特性来决定当前的事务是否应该创建或者挂起。

(1)PROPAGATION_REQUIRED

PROPAGATION_REQUIRED是Spring默认的传播行为,表示调用此方法的事务将包含当前的事务方法中的数据操作,如果外面没有事务,就会新创建一个事务。

以下是一个示例代码:

@Transactional(propagation = Propagation.REQUIRED)
public void updateUser(User user) {
    userDao.updateUser(user);
}

在这个例子中,我们使用@Transactional注解来对 updateUser 方法进行事务封装,该注解的属性 propagation 设置为 REQUIRED,表示方法必须在一个已经存在的事务中运行,如果没有,Spring 会新开一个事务并绑定到当前线程。

(2)PROPAGATION_SUPPORTS

PROPAGATION_SUPPORTS 表示当前方法必须在事务范围内执行,如果当前的方法运行在没有事务的环境下,那么就会以非事务方式运行;如果当前的方法在事务环境下运行,它会加入到当前事务中。

以下是一个示例代码:

@Transactional(propagation = Propagation.SUPPORTS)
public List<User> listUsers() {
    return userDao.listUsers();
}

在这个例子中,我们使用@Transactional注解对 listUsers 方法进行了事务封装,该注解的属性 propagation 设置为 SUPPORTS,表示当前方法需要运行在一个已经存在的事务中,但如果当前环境没有事务,该方法也可以以非事务方式运行。

(3)PROPAGATION_MANDATORY

PROPAGATION_MANDATORY 表示当前方法必须运行在一个事务环境中,否则就会抛出异常。

以下是一个示例代码:

@Transactional(propagation = Propagation.MANDATORY)
public void updateUser(User user) {
    userDao.updateUser(user);
}

在这个例子中,我们使用@Transactional注解对 updateUser 方法进行了事务封装,该注解的属性 propagation 设置为 MANDATORY,代表当前方法必须在一个事务中运行,否则将抛出异常。注意,只有在存在事务的情况下,该方法才能正常执行。

(4)PROPAGATION_REQUIRES_NEW

PROPAGATION_REQUIRES_NEW 表示必须开启一个新的事务,如果当前事务存在,则把当前事务挂起。

以下是一个示例代码:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateUser(User user) {
    userDao.updateUser(user);
}

在这个例子中,我们使用@Transactional注解对 updateUser 方法进行了事务封装,该注解的属性 propagation 设置为 REQUIRES_NEW,代表当前方法必须开启一个新事务,且该事务与外部事务相互独立,互不干扰。该方法执行的过程中,如果外部有事务存在,外部事务会被挂起,待内部事务执行完毕后再恢复外部事务的执行。

(5)PROPAGATION_NOT_SUPPORTED

PROPAGATION_NOT_SUPPORTED 表示当前方法以非事务方式运行,如果当前存在事务,则挂起事务。

以下是一个示例代码:

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void deleteUser(User user) {
    userDao.deleteUser(user);
}

在这个例子中,我们使用@Transactional注解对 deleteUser 方法进行了事务封装,该注解的属性 propagation 设置为 NOT_SUPPORTED,代表当前方法不需要在事务环境中执行,如果当前存在事务就将该事务挂起,方法执行完毕后再恢复外部事务的执行。

(6)PROPAGATION_NEVER

PROPAGATION_NEVER 表示当前方法不应该运行在事务环境中,如果当前存在事务,则抛出异常。

以下是一个示例代码:

@Transactional(propagation = Propagation.NEVER)
public void addUser(User user) {
    userDao.addUser(user);
}

在这个例子中,我们使用@Transactional注解对 addUser 方法进行了事务封装,该注解的属性 propagation 设置为 NEVER,代表当前方法不应该在事务环境中执行,如果当前有事务存在,则抛出异常。

(7)PROPAGATION_NESTED

PROPAGATION_NESTED 表示当前方法必须运行在一个嵌套事务中,如果当前没有事务,则开启一个新的事务。嵌套事务是独立的事务,它能够单独提交或回滚,但是它的提交或回滚操作可能会影响父事务的状态。如果当前的事务方法抛出异常,那么只会回滚本层的事务,而不会回滚整个事务流。

以下是一个示例代码:

@Transactional(propagation = Propagation.NESTED)
public void batchUpdateUser(List<User> users) {
    for (User user : users) {
        userDao.updateUser(user);
    }
}

在这个例子中,我们使用@Transactional注解对 batchUpdateUser 方法进行了事务封装,该注解的属性 propagation 设置为 NESTED,代表当前方法必须运行在一个嵌套事务中,如果当前不存在事务,则开启一个新的事务。在方法执行过程中,多条SQL语句组成一个完整的事务,与外部事务相互独立,但是它的提交或回滚操作可能会影响父事务的状态。

总结

Spring的事务传播特性提供了7种不同的传播行为,可以根据不同的情况来选择合适的传播特性。如果你能够正确地理解和使用事务传播特性,那么就能更好地管理和控制你的事务。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring事物的传播特性详解 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • 得物基于StarRocks的OLAP需求实践详解

    下面是“得物基于StarRocks的OLAP需求实践详解”的完整攻略。 1. 背景 得物是中国领先的社交电商平台之一,数据量非常庞大。在应对这么庞大的数据量时,OLAP技术实现数据查询和分析是一个非常重要的手段。 当然,得物不是一个小公司,他们需要的不仅仅是一个“普通的”OLAP系统,还需要具备可扩展性、高效性和易用性。为此,他们采用了由StarRocks公…

    database 2023年5月18日
    00
  • Linux下MySQL安装配置 MySQL配置参数详解

    Linux下MySQL安装配置 1. 安装MySQL 在Linux中,我们可以通过包管理器(如apt、yum等)来安装MySQL。以下以Ubuntu为例: sudo apt-get update sudo apt-get install mysql-server 安装完成之后,MySQL服务器会自动启动。 2. 配置MySQL 2.1 修改MySQL配置文件…

    database 2023年5月22日
    00
  • 快速解决PostgreSQL中的Permission denied问题

    下面是针对PostgreSQL中的权限问题的完整攻略。 问题概述 在使用PostgreSQL数据库时,可能会遇到Permission denied(权限被拒绝)的问题。这通常是由于当前用户没有足够的权限操作数据库或文件系统导致的。这篇攻略介绍了如何识别和解决这类问题。 识别问题 当你在PostgreSQL中尝试执行某些操作时,如果出现Permission d…

    database 2023年5月18日
    00
  • Oracle如何清除一个用户下的所有表(谨慎操作!)

    清除一个用户下的所有表需要谨慎操作,否则可能导致数据丢失。以下是标准的markdown格式文本,详细讲解Oracle如何清除一个用户下的所有表的完整攻略。 步骤一:确认要删除的用户 在进行任何数据库管理操作之前,请仔细确认要删除的用户。在Oracle数据库中,可以通过以下命令列出所有的用户: SELECT username FROM dba_users; 确…

    database 2023年5月22日
    00
  • win10中docker部署和运行countly-server的流程

    下面是关于在win10中使用docker部署和运行countly-server的完整攻略。 1. 环境准备 在进行docker安装之前,需要先安装一个可靠的虚拟化环境来运行docker。目前在win10平台下,Docker Desktop 被公认为最佳方案。 1.1 安装虚拟化环境 下载并安装VirtualBox。 1.2 安装Docker 下载并安装Doc…

    database 2023年5月22日
    00
  • 详解如何在Linux(CentOS)下重置MySQL根(Root)密码

    下面是详解如何在Linux(CentOS)下重置MySQL根(Root)密码的完整攻略: 1. 关闭MySQL服务 在修改MySQL的密码前,需要先关闭MySQL服务。可以使用以下命令来关闭MySQL服务: sudo systemctl stop mysqld 2. 启动MySQL服务,并跳过授权验证 在 MySQL 5.7.6 之后的版本中,为了保证安全性…

    database 2023年5月22日
    00
  • SQL insert into语句写法讲解

    当我们想要向一个数据库表格里插入新的数据时,可以使用SQL insert into语句。在这里,我将详细讲解如何使用SQL insert into语句来完成这项任务。 SQL insert into语句 SQL insert into语句用来将新的数据插入到一个数据库表格中,在此之前,需要先创建一个表格以存储数据。 以下是SQL insert into语句的…

    database 2023年5月21日
    00
  • 浅谈Linux的库文件

    浅谈Linux的库文件 Linux的库文件是在编译时编译器将程序需要的函数封装成可执行的库文件,以方便程序调用。在使用Linux系统中,有时候会遇到一些库文件相关的问题,因此了解和掌握库文件的相关内容也是很重要的。 库文件的分类 在Linux系统中,有两种类型的库文件:静态库和动态库。 静态库文件(.a文件):将库函数代码直接打包到程序中,因此程序在运行时不…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部