千家信息网

asp.net core之并发冲突的示例分析

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,这篇文章将为大家详细讲解有关asp.net core之并发冲突的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。主要是两种:一种,检查属性并发冲突,使用 [C
千家信息网最后更新 2024年11月23日asp.net core之并发冲突的示例分析

这篇文章将为大家详细讲解有关asp.net core之并发冲突的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

主要是两种:一种,检查属性并发冲突,使用 [ConcurrencyCheck] ;另一种,检测行的并发冲突,使用 rowversion 跟踪属性,如果在保存之前有修改,就报错

发生并发冲突的情况:

1.用户导航到实体编辑页面;

2.第一个用户的更改还未写入数据库之前,另一个用户更新同一实体;

此时,如果未启用并发检测,当发生更新时:

最后一个更新优先。即最后一个更新的值保存到数据库。而第一个保存的值将丢失。

举个例子:

1. Jane 访问 院系 编辑页 面,将英 语 系的 预 算 从 350,000.00 美元更改 为 0.00 美元 (第一个用户把金额改为0)

2. 在 Jane 单击 " 保存 " 之前, John 访问 了相同 页 面,并将开始日期字段从 2007/1/9 更改 为 2013/1/9。 (在第一个用户保存之前,第二个用户把时间从07年改为13年,注意此时第二个用户看到的金额还不是0)

3. Jane 先 单击 " 保存 " ,并在 浏览 器 显 示索引 页时 看到她的更改。 (第一个用户先保存,并且可以在浏览器看到他的修改,金额变0,时间不变)

4.John 单击 " 编辑 " 页 面上的 " 保存 " ,但 页 面的 预 算仍 显 示 为 350,000.00 美元。 (第二个用户保存,此时的页面的预算显示未350000美元,时间为13年)

其实这个结果取决于 并发冲突的处理方式

首先声明,这是一个乐观并发冲突,那么什么是乐观并发冲突呢?

乐观并发冲突允许发生并发冲突,并在并发冲突发生时作出正确的反映。

说了这么多,那么,并发冲突的处理方式呢?

1. 可以跟踪用户已修改的属性,并只更新数据库中相应的列。

这样,当两个用户更新了不同的属性,下次查看时,都将生效。

但是,这种方法,也有一些问题:

  • 当对同一个属性进行竞争性更改的话,无法避免数据丢失

  • 通常不适用于web应用。它需要维持重要状态,以便跟踪所有提取值和新值。 维持大量状态可能影响应用性能。

  • 可能会增加应用复杂性(与实体上的并发检测相比)。

体现在例子中,就是如果 下次有人 浏览 英 语 系 时 ,将看到 Jane 和 John 两个人的更改。

2.客户端优先

即客户端的值优先于数据库存储的值。并且如果不对并发处理进行任何编码,将自动进行客户端优先

即John 的更改覆盖 Jane 的更改 。也就是说,下次有人 浏览 英 语 系 时 ,将看到 2013/9/1 和提取的 值 350,000.00 美元

3.存储优先

这种方式可以阻止在数据库中John的更改。并且可以

  • 显示错误消息

  • 显示数据的当前状态

  • 允许用户重新应用更改。

处理并发

当属性配置 为 并 发 令牌 时 :

数据库和数据模型必须配置为支持引发DbUpdateConcurrencyException 。

检测属性的并发冲突

可使用 ConcurrencyCheck 特性在属性级别检测并发冲突。 该特性可应用于模型上的多个属性 。[ConcurrencyCheck] 特性

检测行的并发冲突

要检测并发冲突,请将 rowversion 跟踪列添加到模型。

注意:rowversion , 

1.它是 SQL Server 特定的。 其他数据库可能无法提供类似功能。

2.用于确定从数据库提取实体后未更改实体。

数据库生成rowversion序号,该数字随着每次行的更新递增。

在 update 或 delete 命令中,where 子句中包括 rowversion提取值 的判断 。

如果要更新的行已经修改,则 rowversion提取值与现在数据库中rowversion的值不匹配;

update 或 delete 命令不能找到行。引发一个 DbUpdateConcurrencyException 异常

例子

向 Department 实 体添加跟踪属性

using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.ComponentModel.DataAnnotations.Schema;namespace ContosoUniversity.Models{public class Department{public int DepartmentID { get; set; }[StringLength(50, MinimumLength = 3)]public string Name { get; set; }[DataType(DataType.Currency)][Column(TypeName = "money")]public decimal Budget { get; set; }[DataType(DataType.Date)][DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)][Display(Name = "Start Date")]public DateTime StartDate { get; set; }public int? InstructorID { get; set; }1607424707public byte[] RowVersion { get; set; } //跟踪属性public Instructor Administrator { get; set; }public ICollection Courses { get; set; }}}

Timestamp 特性 指定此列包含在 update 和 delete 命令的 where 子句中。

也可以用 Fluent API 指定跟踪属性:

modelBuilder.Entity().Property("RowVersion").IsRowVersion();

以下代 码显 示更新 Department 名称 时 由 EF Core 生成的部分 T-SQL :

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

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

@@ROWCOUNT 返回受上一 语 句影响的行数。 在没有行更新的情况下, EF Core 引 发
DbUpdateConcurrencyException

关于"asp.net core之并发冲突的示例分析"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

冲突 数据 属性 用户 更新 数据库 检测 跟踪 实体 应用 特性 处理 浏览 乐观 例子 命令 子句 客户 方式 时间 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 延庆区标准网络技术服务系统 网络安全教育板报材料 天融信在武汉的网络安全学校 dns服务器地址 移动 中学生道德与法治展馆软件开发 以下属于非关系性数据库的 网络安全法多久一次更新 网络安全防御体系表 学生网络安全试卷 大学生网络安全主题班会 如何查看已安装数据库 本科学历转行学网络安全好学吗 金融分享软件开发 感趣网络技术有限公司 无法解析服务器域名或地址 银行软件开发岗位有没有存贷款 网络安全法管理者 梦幻西游选什么服务器 世界网络安全组织会议活动 网络安全法四大热点 网络安全税务信息化 青岛小樱教育网络技术有限公司 瑞思数据库包括什么 冻品互联网络科技有限公司 数据库项目总结感想 四川盛通网络技术有限公司 和网络安全有关的流行歌曲 新一代网络技术体系结构发展前沿 万方数据库研究趋势图怎么看 构建智慧消防软件开发
0