asp.net core 系列之并发冲突的深入理解

 更新时间:2019-06-25 03:01:32   作者:佚名   我要评论(0)

本文介绍如何处理多个用户并发更新同一实 体(同时)时出现的冲突 。


主要是两种:一种,检查属性并发冲突,使用 [ConcurrencyCheck] ;另一种,检测行的并

本文介绍如何处理多个用户并发更新同一实 体(同时)时出现的冲突 。

主要是两种:一种,检查属性并发冲突,使用 [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; }

1561402892
public byte[] RowVersion { get; set; } //跟踪属性

public Instructor Administrator { get; set; }
public ICollection<Course> Courses { get; set; }
}
}

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

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

modelBuilder.Entity<Department>()
.Property<byte[]>("RowVersion")
.IsRowVersion();

以下代 码显 示更新 Department 名称 时 由 EF Core 生成的部分 T-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
), 则 不更新行。

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

此文主要是为了方便自己记录学习,如有错误,欢迎指正

这里附上参考资料:

https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/concurrency?view=aspnetcore-2.2&tabs=visual-studio

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • EF Core 验证提取属性后是否未更改属性。 调用 SaveChanges 或 SaveChangesAsync 时会执行此检查。
  • 如果提取属性后更改了属性,将引发 DbUpdateConcurrencyException。

您可能感兴趣的文章:

  • .net core如何在网络高并发下提高JSON的处理效率详解
  • .net core并发下线程安全问题详解
  • .net core并发请求发送HttpWebRequest的坑解决
  • .NET Core 中的并发编程

相关文章

  • asp.net core 系列之并发冲突的深入理解

    asp.net core 系列之并发冲突的深入理解

    本文介绍如何处理多个用户并发更新同一实 体(同时)时出现的冲突 。 主要是两种:一种,检查属性并发冲突,使用 [ConcurrencyCheck] ;另一种,检测行的并
    2019-06-25
  • 详解.Net Core 权限验证与授权(AuthorizeFilter、ActionFilterAttribute)

    详解.Net Core 权限验证与授权(AuthorizeFilter、ActionFilterAttribute)

    在.Net Core 中使用AuthorizeFilter或者ActionFilterAttribute来实现登录权限验证和授权 一、AuthorizeFilter 新建授权类AllowAnonymous继承AuthorizeFilt
    2019-06-25
  • 浅析.Net Core中Json配置的自动更新

    浅析.Net Core中Json配置的自动更新

    Pre 很早在看 Jesse 的 Asp.net Core快速入门 的课程的时候就了解到了在Asp .net core中,如果添加的Json配置被更改了,是支持自动重载配置的,作为一名有着严重
    2019-06-25
  • .NET开发人员关于ML.NET的入门学习

    .NET开发人员关于ML.NET的入门学习

    ML.NET一直在微软的研究部门的工作。这些创新已经用于他们自己的产品,如Windows Defender,Microsoft Office(Powerpoint设计理念,Excel图表推荐),Azure机
    2019-06-25
  • Windows下Visual Studio 2017安装配置方法图文教程

    Windows下Visual Studio 2017安装配置方法图文教程

    Windows下Visual Studio 2017 安装,具体内容如下 1.打开下载页。 打开VS产品下载页面,链接 2.选择版本下载 选择相应的版本(社区,Professional,企业版)
    2019-06-25
  • 前端Vue项目详解--初始化及导航栏

    前端Vue项目详解--初始化及导航栏

    一、项目初始化 创建webpack模板项目如下所示: MacBook-Pro:PycharmProjects hqs$ vue init webpack luffy_project &#63; Project name luffy_project
    2019-06-25
  • .net core webapi jwt 更为清爽的认证详解

    .net core webapi jwt 更为清爽的认证详解

    我的方式非主流,控制却可以更加灵活,喜欢的朋友,不妨花一点时间学习一下 jwt认证分为两部分,第一部分是加密解密,第二部分是灵活的应用于中间件,我的处理
    2019-06-25
  • ASP.NET Core静态文件的使用方法

    ASP.NET Core静态文件的使用方法

    前言 静态文件(HTML,CSS,图片和Javascript之类的资源)会被ASP.NET Core应用直接提供给客户端。 静态文件通常位于网站根目录(web root) <content-root>/ww
    2019-06-25
  • .NET Core 3.0之创建基于Consul的Configuration扩展组件

    .NET Core 3.0之创建基于Consul的Configuration扩展组件

    经过前面三篇关于.NET Core Configuration的文章之后,本篇文章主要讨论如何扩展一个Configuration组件出来。 了解了Configuration的源码后,再去扩展一个组件
    2019-06-25
  • Pyqt5实现英文学习词典

    Pyqt5实现英文学习词典

    运用Python语言编写程序制作英文学习词典,词典有4个基本功能:添加、查询、删除和退出。程序读取源文件路径下的txt格式词典文件,若没有就创建一个。词典文件
    2019-06-25

最新评论