Razor page-如何处理并发冲突

本文探讨了Web应用中的并发冲突,详细介绍了悲观并发与乐观并发的概念,以及如何通过添加跟踪属性进行冲突检测,确保数据的一致性和完整性。
一. 什么是并发冲突?

在Web应用中, 当一个用户的更改还未提交时,另一用户更新同一数据会产生并发冲突.

二. 如何处理并发冲突

处理并发冲突的方法主要有两大类:

  1. 悲观并发

预防并发冲突的一种方法是使用数据库锁定。 这称为悲观并发。 应用在读取要更新的数据库行之前,将请求锁定。 锁定某一行的更新访问权限之后,其他用户在第一个锁定释放之前无法锁定该行。
缺点: 编程会比较复杂,并且随着用户增加可能会导致性能问题。 Entity Framework Core 未提供对它的内置支持,不推荐!

  1. 乐观并发

乐观并发允许发生并发冲突,并在并发冲突发生时作出正确反应。
如以下提交页面:
在这里插入图片描述
一个用户正准备修改Buget(预算)字段, 而同时另一个用户正提交日期字段的修改. 对于这种并发冲突有以下3种处理方式:

  • 可以跟踪用户修改的属性,并仅更新数据库中相应的列
    在这种情况下,数据不会丢失。 两个用户更新了不同的属性.
    缺点: 无法避免数据丢失;对于 Web 应用。维持大量状态会影响应用性能;
    可能会增加应用复杂性(与实体上的并发检测相比)。不推荐!

  • 客户端优先原则
    也称"最后一个优先” , 客户端的所有值优先于数据存储的值。这是ASP.NET的默认处理原则

  • 存储优先原则
    数据存储值优先于客户端提交的值。
    应用会:显示错误消息; 显示数据的当前状态; 允许用户重新应用更改。

三. 添加跟踪属性进行冲突检测

EF Core 在检测到冲突时会引发 DbConcurrencyException 异常。 数据模型必须配置为启用冲突检测。数据库表中增加一个跟踪更改时间的列。
对于 SQL Server 数据库,定义为byte[]的实体属性上应用 [Timestamp] 特性:

  • 使列包含在 DELETE 和 UPDATE WHERE 子句中。
  • 将数据库中的列类型设置为 rowversion。

数据库将生成有序的行版本号,该版本号随着每次行的更新递增。 在 Update 或 Delete 命令中,Where 子句包括提取的行版本值。 如果要更新的行在提交时发现:

  • 当前的行版本值与提取值不相匹配。
  • Update 或 Delete 命令不查找行,因为 Where 子句会查找提取行的版本值。
  • 引发一个 DbUpdateConcurrencyException。

EF Core更新数据时生成的SQL语句如下

SET NOCOUNT ON;
UPDATE [Department] SET [Name] = @p0
WHERE [DepartmentID] = @p1 AND [RowVersion] = @p2;
SELECT [RowVersion]
FROM [Department]
WHERE @@ROWCOUNT = 1 AND [DepartmentID] = @p1;

代码显示包含 RowVersion 的 WHERE 子句。 如果数据库 RowVersion 不等于 RowVersion 参数 (@p2),则不更新行, 同时引发 DbUpdateConcurrencyException。

提交更改时, EF Core 会对比客户端与数据库中的RowVersion值, 如果不一致会触发DbUpdateConcurrencyException异常, 我们只要捕捉此异常并做相应处理即可!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值