Spring事物的传播特性详解

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日

相关文章

  • MySQL数据库:聚合函数的使用

    聚合函数 max() 最大值min() 最小值avg() 平均值sum() 求和count() 符合条件数据的数目 聚合函数不能嵌套使用 # 在统计时字段内没有满足条件的数值只有count返回数值0或者其他,而其余四个聚合函数返回null; # 对于聚合函数的参数,很多时候使用字段名来表示,那么这个时候,该字段内的null值不参与统计 count(*) 显示…

    MySQL 2023年4月13日
    00
  • MySQL 中 的 bit 类型,tinyint(1);

    之前一直以为 mysql中没有 bit类型,需要使用 tinyint 来标识 bit。但是前端的实体类,不好控制,后来发现这些问题已经有了默认的统一设置,这样反而更好。   总结:MySQL中 使用布尔类型的字段,就用 tinyint(1),true 为1 false 为0 辅助参考文章:https://blog.csdn.net/dianjun2454/a…

    MySQL 2023年4月13日
    00
  • oracle数据库中sql%notfound的用法详解

    Oracle数据库中SQL%NOTFOUND的用法详解 引言 在操作Oracle数据库时,SQL%NOTFOUND是一个常用的关键字,它通常用于检查SQL语句执行操作是否成功。在本文中,我们将详细讲解这个关键字的用法。 什么是SQL%NOTFOUND SQL%NOTFOUND是Oracle数据库中的内置一个关键字,在SQL执行完毕后会返回一个布尔值,并表示该…

    database 2023年5月21日
    00
  • 一文带你学会MySQL的select语句

    一文带你学会MySQL的select语句 在MySQL中,常用的语句之一就是SELECT语句,用于从数据库中获取需要的数据。下面将从语法、用法等方面详细介绍SELECT语句的使用。 语法 SELECT 列名或表达式 FROM 表名 WHERE 条件 GROUP BY 分组列名 HAVING 分组条件 ORDER BY 排序列名 [ASC|DESC] LIMI…

    database 2023年5月21日
    00
  • MySql8 WITH RECURSIVE递归查询父子集的方法

    当我们需要查询数据中某个节点的所有子节点或父节点时,使用递归查询是一种非常方便的解决方案。MySQL 8 提供了一个WITH RECURSIVE语法来实现递归查询。下面是递归查询父子集的完整攻略: 1. 建立测试数据库 为了演示示例,我们需要先建立一个测试数据库,并在该数据库中建立一个包含parent_id字段的表。 CREATE DATABASE test…

    database 2023年5月22日
    00
  • mysql多表联合查询返回一张表的内容实现代码

    实现mysql多表联合查询中返回一张表的内容,可以通过使用UNION ALL操作符,将多个SELECT语句的结果集组合成一个结果集,最后将所有的查询结果拼成一个表。 下面是具体的实现步骤: 找到需要联合查询的多张表,根据关联字段进行连接操作(JOIN),例如连接表A和表B: SELECT A.*, B.* FROM table_A A INNER JOIN …

    database 2023年5月22日
    00
  • PouchDB 和 MariaDB 的区别

    PouchDB和MariaDB是两种不同类型的数据库,它们最明显的区别在于PouchDB是面向客户端的本地数据库,而MariaDB是一种关系型数据库。 PouchDB是一个在浏览器端和移动端上运行的JavaScript数据库,与其他数据库不同的是,PouchDB允许用户建立本地数据库,存储和数据库操作都是在客户端进行的。这使得PouchDB非常适合离线应用程…

    database 2023年3月27日
    00
  • 使用Java编写控制JDBC连接、执行及关闭的工具类

    下面我就给您详细讲解一下使用Java编写控制JDBC连接、执行及关闭的工具类的攻略。 什么是JDBC? JDBC (Java Database Connectivity,Java数据库连接) 是一种用于执行 SQL 语句的 Java API,可以方便的访问各种关系型数据库。 JDBC连接数据库的步骤 JDBC连接数据库主要分成以下几个步骤: 加载数据库驱动:…

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