浅谈spring中isolation和propagation的用法

我们来一步步详细讲解。

简介

在Spring中,@Transactional注解可以用于标注事务处理的方法,其中isolationpropagation两个属性用来设置事务的隔离级别和传播特性。本文将主要围绕这两个属性展开讲解。

隔离级别

事务隔离级别是解决数据库并发访问引发的一系列问题的标准。Spring框架提供了五种不同的隔离级别,分别是:

  • ISOLATION_DEFAULT:采用默认的数据库隔离级别。
  • ISOLATION_READ_UNCOMMITTED:读取未提交的数据,该隔离级别存在数据不一致的问题。
  • ISOLATION_READ_COMMITTED:读取已提交的数据,可以避免脏读问题。
  • ISOLATION_REPEATABLE_READ:可以多次读取同一件事物的数据,可以防止脏读和不可重复的读问题。
  • ISOLATION_SERIALIZABLE:最高的隔离级别,可以防止脏读、不可重复的读和幻读问题。

传播特性

在Spring框架中,一个事务方法内部还可以调用其他事务方法,这时就需要使用传播特性来控制事务的传播方式。Spring提供了7种传播特性,分别是:

  • PROPAGATION_REQUIRED:如果当前存在一个事务,则加入该事务,否则创建一个新事务。
  • PROPAGATION_SUPPORTS:如果当前存在一个事务,则加入该事务,否则按非事务方式执行。
  • PROPAGATION_MANDATORY:如果当前存在一个事务,则加入该事务,否则抛出异常。
  • PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则将当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务中执行。如果没有事务则按照REQUIRED执行。

示例

下面我们通过两个示例来演示这两个属性。

示例1:隔离级别的设置

/**
 * 隔离级别的示例类
 */
@Service
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
public class IsolationService {

    @Autowired
    private UserDao userDao;

    /**
     * 转账方法
     *
     * @param from   转出账户
     * @param to     转入账户
     * @param amount 转账金额
     */
    public void transfer(String from, String to, double amount) {

        // 查询转出账户并扣除余额
        User fromUser = userDao.getUserByName(from);
        fromUser.setAmount(fromUser.getAmount() - amount);
        userDao.updateUser(fromUser);

        // 查询转入账户并增加余额
        User toUser = userDao.getUserByName(to);
        toUser.setAmount(toUser.getAmount() + amount);
        userDao.updateUser(toUser);

    }
}

在上面的示例中,我们通过@Transactional注解设置了事务的隔离级别为ISOLATION_REPEATABLE_READ,传播特性为PROPAGATION_REQUIRES_NEW

该示例中的transfer方法用于实现两个用户之间的转账操作,其中查询用户并修改余额的过程,需要保证在同一个事务中执行,而且在查询不同用户的余额时也需要保证数据的一致性,因此需要将事务的隔离级别设置为ISOLATION_REPEATABLE_READ

而且在转账过程中,如果出现异常需要回滚时,需要只回滚当前事务,而不回滚之前的事务,因此需要将传播特性设置为PROPAGATION_REQUIRES_NEW

示例2:传播特性的设置

/**
 * 传播特性的示例类
 */
@Service
@Transactional
public class PropagationService {

    @Autowired
    private IsolationService isolationService;

    @Autowired
    private UserDao userDao;

    public void withdraw(String userName, double amount) {

        User user = userDao.getUserByName(userName);
        user.setAmount(user.getAmount() - amount);
        userDao.updateUser(user);

    }

    public void transfer(String from, String to, double amount) {

        isolationService.transfer(from, to, amount);

    }

    public void pay(String from, String to, double amount) {

        // 模拟支付过程
        withdraw(from, amount);

        // 模拟转账过程
        transfer(from, to, amount);

    }

}

在上面这个示例中,我们实现了一个支付流程,其中模拟了从一个用户账户中扣款和向另一个用户账户转账两个操作。这两个操作都是在事务内部进行的。而在最终的支付流程中,需要先完成扣款操作,然后再进行转账操作。也就是说,如果扣款操作失败,则转账操作不应该执行。

但是如果我们只在withdraw方法上加@Transactional注解,而不加在pay方法上,则在withdraw方法执行之后,即使发生异常,余额也已经被减少了,这是不可取的。因此,我们需要将pay方法也加上@Transactional注解,并设置其传播特性为PROPAGATION_REQUIRES_NEW,这样才能做到各自独立的事务,出现异常时互不干扰。

总结

在Spring框架中,@Transactional注解是非常常用的,特别是在服务层开发中。isolationpropagation两个属性可以用于控制事务的隔离级别和传播特性,帮助我们实现各种不同的事务场景。掌握这两个属性的使用方式,对于实现可靠的业务逻辑非常重要。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈spring中isolation和propagation的用法 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 15个简单的JS编码标准让你的代码更整洁(小结)

    15个简单的JS编码标准让你的代码更整洁(小结) 本文为大家整理了15个简单的javascript编码标准,帮助开发人员写出更加干净整洁的代码,提高可维护性和可读性。 1. 使用=== 比较运算符 使用=== 比较运算符可以避免类型不同比较混淆和类型自动转换的问题。 2. 使用const 或 let, 不使用 var 使用 const 或 let 比 var…

    JavaScript 2023年5月18日
    00
  • JavaScript小技巧 2.5 则

    完整攻略如下: JavaScript小技巧 2.5则 简介 这是第二篇JavaScript小技巧的第五则,本篇攻略将详细讲解如何利用JavaScript小技巧来提高开发效率和代码的可读性。 正文 小技巧1:使用数组解构赋值获取函数的多个返回值 在JavaScript中,函数可以有多个返回值,如果我们需要获取这些返回值并分别进行操作,那么可以使用数组解构赋值来…

    JavaScript 2023年5月27日
    00
  • 利用fecha进行JS日期处理

    日期是我们在开发过程中运用最广泛的数据类型之一。JavaScript中有很多原生的日期处理方法,但也存在一些缺点,例如有时候会显示不正确的时区或格式,因此有必要使用第三方库进行日期处理。其中一个优秀的库就是fecha。下面将为大家详细介绍如何使用该库进行JS日期处理。 1. 安装fecha 首先需要在项目中安装fecha库,可以使用npm进行安装。 npm …

    JavaScript 2023年6月11日
    00
  • JavaScript实现动态网页飘落的雪花

    一、前言 在网页设计中,为了增加节日气氛或者美化页面,经常会配上一些漂亮的特效。其中,飘雪效果是比较常见的一个效果。本篇文章主要介绍JavaScript实现动态网页飘落的雪花的详细攻略。 二、基本思路 主要思路是使用setInterval()函数对页面中的每一个雪花进行计算、控制其位置以及更新其状态,并使用CSS和HTML控制每个雪花的样式以及雪花的总数。 …

    JavaScript 2023年6月10日
    00
  • Javascript 构造函数详解

    Javascript 构造函数详解 Javascript中的构造函数是一种用于创建对象的特殊函数,它可以通过使用关键字 new 来调用,并返回新创建的实例对象。 构造函数定义 构造函数的定义形式与普通函数相同,不同的是构造函数的名称通常首字母大写,以便于区分。 function Person(name, age) { this.name = name; th…

    JavaScript 2023年5月27日
    00
  • 用YUI做了个标签浏览效果

    让我来详细讲解如何用YUI库来实现标签浏览效果的完整攻略。 YUI库简介 YUI(Yahoo! User Interface Library)是雅虎公司推出的一个用于创建富交互性Web应用的JavaScript库,提供了一系列的工具和组件,方便开发人员开发Web应用。YUI组件包括DOM操作、事件管理、动画、日历、数据源、表单控件、图像轮换、布局管理、菜单、…

    JavaScript 2023年6月11日
    00
  • JS简单获取客户端IP地址的方法【调用搜狐接口】

    JS简单获取客户端IP地址的方法【调用搜狐接口】 获取客户端IP地址是一种常见的需求,而JavaScript作为Web开发的主流语言,有时候需要通过JS获取客户端的IP地址。下面介绍一种简单的方式:调用搜狐接口。 1. 搜狐IP地址接口 搜狐提供了一个IP地址查询接口,可以通过该接口获取到访问者的IP地址和地理位置信息。接口地址为:http://pv.soh…

    JavaScript 2023年6月10日
    00
  • JavaScript数组合并的多种方法

    下面是“JavaScript数组合并的多种方法”的完整攻略。 方法一:concat() concat() 方法将两个或多个数组合并成一个新数组。 使用示例 const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const arr3 = arr1.concat(arr2); console.log(arr3); // …

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