如何在 EF Core 中使用乐观并发控制

这篇具有很好参考价值的文章主要介绍了如何在 EF Core 中使用乐观并发控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如何在 EF Core 中使用乐观并发控制

什么是乐观并发控制?

乐观并发控制是一种处理并发访问的数据的方法,它基于一种乐观的假设,即认为并发访问的数据冲突的概率很低。在乐观并发控制中,系统不会立即对并发访问的数据进行加锁,而是在数据被修改时,再检查是否有其他并发操作已经修改了数据。如果检测到冲突,系统 再采取相应的措施来解决冲突。

EF Core 内置了使用并发令牌列实现的乐观并发控制,所谓的并发令牌列通常就是被并发操作影响的列。请看本文是如何在 EF Core 中使用乐观并发控制的……

使用步骤

  1. 创建一个 Asp.net console 项目,并从 Nuget 引用 EF 相关的包

    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore.Tools

  2. 配置并发冲突列

    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata.Builders;
    
    class HouseConfig : IEntityTypeConfiguration<House>
    {
    	public void Configure(EntityTypeBuilder<House> builder)
    	{
    		builder.ToTable("T_Houses");
    		builder.Property(p => p.Name).IsUnicode().IsRequired();
    		// 把 Owner 列配置为并发令牌
    		builder.Property(p => p.Owner).IsConcurrencyToken();
    	}
    }
    
  3. 在 Program.cs 编写以下代码:

    using Microsoft.EntityFrameworkCore;
    
    Console.WriteLine("请输入您的姓名");
    string name = Console.ReadLine()!;
    using TestDbContext ctx = new TestDbContext();
    
    // 1.获取数据
    var h1 = await ctx.Houses.SingleAsync(h => h.Id == 1);
    if (string.IsNullOrEmpty(h1.Owner))
    {
    	// 2.延迟5秒,方便测试
    	await Task.Delay(5000);
    
    	// 3.更新数据
    	h1.Owner = name;
    	try
    	{
    		await ctx.SaveChangesAsync();
    		Console.WriteLine("抢到手了");
    	}
    	catch(DbUpdateConcurrencyException ex)
    	{
    		// 4. 捕捉和处理并发冲突
    		var entry = ex.Entries.First();
    		var dbValues = await entry.GetDatabaseValuesAsync();
    		string newOwner = dbValues.GetValue<string>(nameof(House.Owner));
    		Console.WriteLine($"并发冲突,被{newOwner}提前抢走了");
    	}
    }
    // 5.处理数据已存在情况
    else
    {
    	if (h1.Owner == name)
    	{
    		Console.WriteLine("这个房子已经是你的了,不用抢");
    	}
    	else
    	{
    		Console.WriteLine($"这个房子已经被{h1.Owner}抢走了");
    	}
    }
    Console.ReadLine();
    
  4. 测试

    1. 清理 T_Houses 表数据,让 Owner 列等于 null
    2. 同时运行两个控制台程序
    3. 在第一个控制台程序输入 Tom 并运行
    4. 在第二个控制台程序输入 Jim 并运行
    5. 第一个控制台返回消息:抢到手了
    6. 第二个控制台则返回消息:并发冲突,被Tom提前抢走了

扩展

  1. 通常可以通过把并发修改的属性设置为并发令牌的方式启用乐观并发控制。

  2. 有时候无法确定到底哪个属性适合作为并发令牌,比如程序在不同的情况下会更新不同的列或者程序会更新多个列,在这种情况下,可以使用设置一个额外的并发令牌属性的方式来使用乐观并发控制。

  3. 如果使用Microsoft SQL Server数据库,可以用一个byte[]类型的属性作为并发令牌属性,然后使用IsRowVersion把这个属性设置为RowVersion类型,这个属性对应的数据库列就会被设置为ROWVERSION类型。对于ROWVERSION类型的列,在每次插入或更新行时,Microsoft SQL Server会自动为这一行的ROWVERSION类型的列生成新值。

    1. 增加一个额外的byte[]类型的属性
    class House
    {
       public long Id { get; set; }
       public string Name { get; set; }
       public string? Owner { get; set; }
       public byte[] RowVer { get; set; }
    }
    
    2. 配置并发令牌
    builder.ToTable("T_Houses");
    builder.Property(h => h.Name).IsUnicode();
    builder.Property(h => h.RowVer).IsRowVersion();
    
    3. Update 语句中的 Where 中使用 RowVer 列
    
  4. 其它数据库也可以使用 Guid 作为并发令牌控制

  5. 乐观并发控制能够避免悲观锁带来的性能下降、死锁等问题,推荐使用乐观并发控制而不是悲观锁文章来源地址https://www.toymoban.com/news/detail-762346.html

到了这里,关于如何在 EF Core 中使用乐观并发控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • EF Core 在实际开发中,如何分层?

    分层就是将 EF Core 放在单独的项目中,其它项目如 Asp.net core webapi 项目引用它 这样的好处是解耦和项目职责的清晰划分,并且可以重用 EF Core 项目 但是也会数据库迁移变得复杂起来 创建一个 .NET 类库项目,项目名字为 BooksEFCore 引用以下 Nuget 包 Microsoft.EntityFrameworkCore.Relati

    2024年01月24日
    浏览(35)
  • 【数据库】基于时间戳的并发访问控制,乐观模式,时间戳替代形式及存在的问题,与封锁模式的对比

    ​ 专栏内容 : 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学

    2024年02月03日
    浏览(35)
  • 使用EF Core创建webapi接口(二)

    有错误欢迎大家给我指正 说明:netcore webapi+net6+EF Core版本,codefirst模式(代码创建数据库) 1.netcore webapi+net6+EF Core版本,dbfirst模式(代码生成数据库)见:使用EF Core创建webapi接口(一)-CSDN博客 2.netcore webapi+net6+EF Core+vue前后端联动版本,见netcore webapi+net6+EF Core+vue3前后端联动-CSD

    2024年02月21日
    浏览(36)
  • Net Core中使用EF Core连接Mysql数据库

    Entity Framework Core的前身是微软提供并主推的ORM框架,简称EF,其底层是对ADO.NET的封装。EF支持SQLServer、MYSQL、Oracle、Sqlite等所有主流数据库。 首先是使用时的几个模式的整理及其理解: Code First:根据代码自动创建数据库表结构甚至是数据库,可以支持多库开发,代码较少冗余

    2024年01月24日
    浏览(41)
  • ASP.NET Core Web API入门之三:使用EF Core

    一般来讲我们做项目都会用实体类跟数据库实体进行关系对应,这样的好处方便我们维护、增删改查,并且可以减少SQL的编写,从而统一风格,那么 Entity Framework Core 就是很不错的ORM框架。 1、跨数据库支持能力强大,只需修改配置就可以轻松实现数据库切换。 2、提升了开发效

    2024年02月10日
    浏览(43)
  • EF.Core 使用Linq的Contact联合查询问题

    在.net Core 5 WebAPI 项目中应用 EF Core 5 实体框架,使用Linq的Contact联合进行多表查询。 定义两个子查询语句,查询结果 select 返回的对象结构类型都是一致的。 Linq查询结果集封装对象类: DatingComplaint 实体类映射(Fluent API): 但在执行到 ToListAsync() 代码行查询返回结果时,抛

    2024年02月13日
    浏览(31)
  • .NET使用一行命令轻松生成EF Core项目框架

    dotnet ef是Entity Framework Core(EF Core)的一个命令行工具,用于管理EF Core应用程序的数据库和代码。除了提供管理数据库的命令之外,dotnet ef还可以生成和管理实体和上下文代码。本文将介绍如何使用dotnet ef动态生成代码。 一、环境准备 1、项目准备 用vs2022新建一个.NET6的asp.

    2023年04月27日
    浏览(40)
  • NET8 ORM 使用AOT SqlSugar 和 EF Core

    .Net8的本地预编机器码NET AOT,它几乎进行了100%的自举。微软为了摆脱C++的钳制,做了很多努力。也就是代码几乎是用C#重写,包括了虚拟机,GC,内存模型等等。而需要C++做的,也就仅仅是引导程序,本篇通过代码来看下这段至关重要的引导程序的运作模式。      SqlSugar已经

    2024年02月05日
    浏览(41)
  • 【解惑】当处理同一个字段的并发问题时,使用乐观锁来处理库存数量

    以下是一个使用乐观锁处理库存数量并发问题的c#示例代码: 上述示例代码使用乐观锁来处理并发问题,确保库存数量在更新过程中不受影响。通过使用数据库事务来保证更新的原子性,并且在更新数据之前检查版本号是否一致,以避免潜在的并发冲突。 乐观锁是一种乐观的

    2024年02月13日
    浏览(24)
  • .net core 创建WebAPI以及使用EF DBFirst框架使用方法与疑问解答(.net 6)

    EF语法包: 生成实体模型: 修改实体模型: 把生成的实体和上下文都输出到某个文件夹命令 增加JSON格式脚手架: 若想增加某个版本json脚手架,需要加入后缀如: 问题与解决方案: 1、问题: Your startup project \\\'XXX\\\' doesn\\\'t reference Microsoft.EntityFrameworkCore.Design. This package is requi

    2024年02月16日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包