Web API乐观锁和悲观锁

在 Web API 中,乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)是两种常见的并发控制机制。它们的目的都是在多个用户同时访问和修改相同资源时,确保数据的一致性和完整性。

乐观锁

乐观锁的思想是假设并发访问的操作不会造成冲突,因此在读取和修改资源时不加锁,而是通过版本号或时间戳等机制来检测并发冲突。当两个或多个用户同时修改同一资源时,系统会比对版本号或时间戳,并根据结果判断是否发生了冲突。如果发生了冲突,可以选择回滚事务或采取其他处理方式。
在 Web API 中实现乐观锁通常涉及以下步骤:

  • 在数据模型中增加一个版本号字段或时间戳字段。
  • 在更新操作中比对客户端提交的版本号或时间戳与数据库中的值是否一致。
  • 如果一致,则执行更新操作并递增版本号或更新时间戳。
  • 如果不一致,则说明发生了并发冲突,根据业务需求进行相应的处理,例如返回冲突错误信息或重新尝试操作。
// 定义数据模型,包含版本号字段
public class Order
{public int Id { get; set; }public string ProductName { get; set; }public int Quantity { get; set; }public int Version { get; set; }
}
// 定义更新操作接口
[HttpPut("{id}")]
public async Task<IActionResult> UpdateOrder(int id, [FromBody] Order order)
{// 查询数据库中的订单记录var existingOrder = await _dbContext.Orders.FindAsync(id);// 检查版本号是否一致if (existingOrder.Version != order.Version){return Conflict("The order has been updated by another user. Please refresh and try again.");}// 更新订单记录,并递增版本号existingOrder.ProductName = order.ProductName;existingOrder.Quantity = order.Quantity;existingOrder.Version++;// 提交事务try{await _dbContext.SaveChangesAsync();}catch (DbUpdateConcurrencyException ex){// 处理并发冲突异常return Conflict("The order has been updated by another user. Please refresh and try again.");}// 返回更新后的订单记录return Ok(existingOrder);
}

我们通过检查客户端提交的订单记录的版本号与数据库中的版本号是否一致来判断是否发生了并发冲突。如果版本号不一致,则返回冲突错误信息;否则,更新数据库中的订单记录,并递增版本号,最后返回更新后的订单记录。

需要注意的是,如果多个用户同时修改同一条订单记录,只有一个用户能够成功地提交更新操作,其他用户需要重新获取最新版本的订单记录并重新尝试更新。这种机制可以有效地避免并发冲突,确保数据的一致性和完整性。

悲观锁

悲观锁的思想是假设并发访问的操作会造成冲突,因此在读取和修改资源时会加锁,阻止其他用户同时修改。悲观锁通常使用数据库的锁机制实现,如行级锁或表级锁。
在 Web API 中实现悲观锁通常需要对数据源进行加锁操作,以确保资源的独占性。具体实现方式包括:

  • 使用关系型数据库提供的事务和锁机制,在读取和修改资源时加锁,并释放锁。
  • 使用分布式锁机制,如 Redis 分布式锁,在操作期间将资源锁定,并在操作完成后释放锁。
  • 需要注意的是,悲观锁可能会带来性能开销,并且在高并发情况下可能导致资源争用和死锁等问题。因此,在选择使用乐观锁还是悲观锁时,需要根据具体场景和需求进行权衡和选择。
  • 无论是乐观锁还是悲观锁,在实际应用中都需要综合考虑数据一致性、并发性能和系统复杂度等因素,选择适合的并发控制策略。
// 定义数据库上下文
public class ApplicationDbContext : DbContext
{public DbSet<Order> Orders { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){// 在数据库中创建唯一索引,用于加锁modelBuilder.Entity<Order>().HasIndex(o => o.Id).IsUnique().HasFilter(null);}
}
// 定义数据模型
public class Order
{public int Id { get; set; }public string ProductName { get; set; }public int Quantity { get; set; }
}
// 定义更新操作接口
[HttpPut("{id}")]
public async Task<IActionResult> UpdateOrder(int id, [FromBody] Order order)
{// 加锁using (var dbContextTransaction = await _dbContext.Database.BeginTransactionAsync()){try{// 查询数据库中的订单记录并加锁var existingOrder = await _dbContext.Orders.FirstOrDefaultAsync(o => o.Id == id, cancellationToken: dbContextTransaction.GetDbTransaction().Connection);if (existingOrder == null){return NotFound();}// 更新订单记录existingOrder.ProductName = order.ProductName;existingOrder.Quantity = order.Quantity;// 提交事务await _dbContext.SaveChangesAsync();await dbContextTransaction.CommitAsync();}catch (Exception){// 处理异常await dbContextTransaction.RollbackAsync();throw;}}// 返回更新后的订单记录return Ok(order);
}

我们通过使用数据库事务和行级锁机制实现悲观锁。在更新操作开始时,我们通过查询数据库并加锁获取订单记录。然后,我们对订单记录进行更新,最后提交事务。如果在更新过程中发生异常,将回滚事务并处理异常。

注意

悲观锁使用了数据库的锁机制,确保了资源的独占性,但也可能带来性能开销和并发性能问题。因此,在使用悲观锁时需要谨慎考虑,并根据具体情况进行权衡和选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/609596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的网络设置

一.查看网络配置 1.查看网络接口信息 - ifconfig ① 直接使用 ifconfig 命令 默认显示活动的网卡 解析&#xff1a; ② ifconfig 具体网卡名称 只显示具体的网卡的信息 ③ ifconfig -a 显示所有的网卡 ④ ifconfig 网卡名称 down 关闭网卡 ifdown 关闭网卡 …

2024年01月微软更新Bug 已解决 !Explorer.EXE 提示:Windows无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目。

前倾概要 近期大量出现如上图问题&#xff0c;杀毒&#xff0c;系统急救箱都没反应&#xff0c;罪魁祸首就是微软更新&#xff01; 点击什么都是&#xff1a;Windows无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目。 但软件使用正常&#xff0c;还能通过建立…

MATLAB中slist函数用法

目录 语法 说明 示例 显示模型的已排序列表 slist函数的功能是在模拟调试会话期间显示已排序的模块列表。 语法 slist 说明 slist在MATLAB命令窗口中显示根系统以及根系统中的每个非虚拟子系统或引用模型的块的已排序列表。对于根系统、每个非虚拟子系统和每个引用模型&…

linux离线安装git

首先需要有一台有网的linux&#xff0c;下载git源码包 下载地址 Index of /pub/software/scm/git/ 我这里下载的是git-2.9.5.tar.gz&#xff0c;依次执行如下命令进行编译 # 在有网的环境中&#xff0c;编译git&#xff0c;然后打包拿到内网直接用 # 下载git-2.9.5.tar.gz&…

SQL Server 加密 view文本

CREATE VIEW dbo.View_building WITH ENCRYPTION AS SELECT * FROM Building_Temp; GO 注意&#xff1a; 加密後就看不到VIEW文本了&#xff0c;修改 ALTER VIEW dbo.View_building WITH ENCRYPTION AS –修改後的VIEW 文本 GO 或者刪除再新增。 所以&#xff0c;要另備份原V…

【产品应用】一体化伺服电机在管道检测机器人中的应用

一体化伺服电机在管道检测机器人的应用正日益受到关注。管道检测机器人是一种能够在管道内部进行检测和维护的智能化设备&#xff0c;它可以检测管道的内部结构、泄漏、腐蚀等问题&#xff0c;以确保管道的安全和稳定运行。而一体化伺服电机作为机器人的动力源&#xff0c;对于…

20230403读书笔记|《苏轼词集》——试问岭南应不好,此心安处是吾乡

20230403读书笔记|《苏轼词集》——试问岭南应不好&#xff0c;此心安处是吾乡 导读卷一卷二卷三 在书架里加了好几本苏轼词集&#xff0c;很多词是重复的&#xff0c;但这并不影响多读几本&#xff0c;苏轼的词豪迈大气&#xff0c;豁达爽朗&#xff0c;蛮值得一读的。有不少都…

中小型家具制造业使用制造管理MES系统应该注意什么?

随着人们生活水平变高&#xff0c;人们对家具的要求也在提高。为了应对越来越高的要求&#xff0c;企业开始寻找更有效的方法&#xff0c;其中就包括mes系统&#xff0c;那么中小型家具企业在使用mes的过程中应该注意什么呢&#xff1f; 第一&#xff0c;要考虑选择什么样的mes…

Pycharm直接从github上下载项目(社区版)

Pycharm直接从github上下载项目&#xff08;社区版&#xff09; 1.在pycharm上关联github账号2.导航栏——Git——clone 1.在pycharm上关联github账号 2.导航栏——Git——clone

【数据结构】二叉树的链式实现

树是数据结构中非常重要的一种&#xff0c;在计算机的各方个面都有他的身影 此篇文章主要介绍二叉树的基本操作 目录 二叉树的定义&#xff1a;二叉树的创建&#xff1a;二叉树的遍历&#xff1a;前序遍历&#xff1a;中序遍历&#xff1a;后序遍历&#xff1a;层序遍历&#…

梯度提升决策树(Gradient Boosting Decision Trees,GBDT)

梯度提升决策树&#xff08;Gradient Boosting Decision Trees&#xff0c;GBDT&#xff09; ​ 提升树是以分类树或回归树为基本分类器的提升方法。 提升树被认为是统计学习 中性能最好的方法之一。 ​ 提升方法实际采用加法模型(即基函数的线性组合)与前向分步算法。 以决策…

Mendeley Word 文献引用

这里写目录标题 1. 下载Mendeley 并插入到Word1.1 下载安装1.2 在Word 中添加Mendeley 插件文献引用相关 1. 下载Mendeley 并插入到Word 1.1 下载安装 Mendeley 官网下载 1.2 在Word 中添加Mendeley 插件 打开 Mendeley&#xff0c;点击 Tools —>Install Mendeley Cite…

AWS云用户创建

问题 需要给工友创建AWS云的用户&#xff0c;这里假设使用分配给自己AWS开发者IAM账号&#xff0c;给别人创建aws IAM账号。 登录系统 打开页面&#xff1a;https://xxx.signin.aws.amazon.com/console&#xff0c;使用分配的开发者账号登录。如下图&#xff1a; 创建用户…

资源分享栏目一直会更新

文章目录 1. [南京大学IT侠文档共享计划](https://www.yuque.com/itxia)2. [洛谷OJ平台](https://www.luogu.com.cn/)3. [ChatGPT](chat.openai.com)4. [stackoverflow](stackoverflow.com) 1. 南京大学IT侠文档共享计划 可以解决大部分的电脑问题&#xff0c;如遇到Windows 系…

vue组件开发

1. 组件开发介绍 ① 组件化&#xff1a;一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为。 好处&#xff1a;便于维护&#xff0c;利于复用 → 提升开发效率。 组件分类&#xff1a;普通组件、根组件。② 根组件&#xff08;App.vue&#xf…

Hive之set参数大全-5

I 限制外部表数据插入 set hive.insert.into.external.tablestrue;在Apache Hive中&#xff0c;通过INSERT INTO语句向外部表&#xff08;External Table&#xff09;插入数据时&#xff0c;有一些注意事项和限制。外部表是Hive中的一种特殊表&#xff0c;它与Hive管理的存储…

探索Redis特殊数据结构:HyperLogLog在基数统计中的应用

一、概述 Redis官方提供了多种数据类型&#xff0c;除了常见的String、Hash、List、Set、zSet之外&#xff0c;还包括Stream、Geospatial、Bitmaps、Bitfields、Probabilistic&#xff08;HyperLogLog、Bloom filter、Cuckoo filter、t-digest、Top-K、Count-min sketch、Confi…

Mariadb和mysql数据库的区别和相同之处

目 录 一、maridb 和mysql在linux系统中广泛应用 二、MySQL数据库 三、MariaDB数据库 四、MariaDB和MySQL有哪些相同点 五、MariaDB和MySQL的不同点 一、mariadb 和mysql在linux系统中广泛应用 用linux&#xff08;包括centos和Ubuntu&#xff09;的都知道&a…

使用Trie数据结构实现搜索自动完成功能

本文旨在讨论使用 Java 的搜索自动完成的低级实现&#xff0c;将Trie在用例中使用数据结构。 这是一个示例TrieNode类&#xff1a; class TrieNode{ Map<Character,TrieNode> children; boolean isEndOfWord; TrieNode(){ children new HashMap<>(); isEndOfWor…

Unity 利用UGUI之Scrollbar制作进度条

在Unity中除了用Slider、Image做进度条&#xff0c;其实用Scrollbar也可以做进度条。 首先&#xff0c;在场景中新建一个Scrollbar组件和一个Text组件&#xff1a; 其次&#xff0c;创建模拟进度的一个脚本&#xff0c;Scrollbar_Progressbar.cs: using System.Collections; …