当前位置: 首页 > article >正文

EFCore乐观并发

在 Entity Framework Core 中,乐观并发是一种处理并发访问的方式,它允许多个用户同时访问和修改相同的数据,而不会发生冲突。乐观并发的实现通常涉及使用版本控制字段来检测数据更改,并在保存更改时检查这些字段是否与预期值匹配。

以下是在 Entity Framework Core 中实现乐观并发的一般步骤:

  1. 为实体模型添加一个用于乐观并发的版本属性。这通常是一个用于标识数据版本的属性,可以是整数、时间戳等。
public class Entity
{
    public int Id { get; set; }
    public string Name { get; set; }
    [Timestamp]
    public byte[] Version { get; set; } // 乐观并发的版本属性
}
  1. 在配置实体模型时,告诉 Entity Framework Core 使用版本属性进行乐观并发检查。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Entity>()
        .Property(e => e.Version)
        .IsConcurrencyToken(); // 告诉 EF 使用 Version 属性进行乐观并发检查
}
  1. 当更新实体时,Entity Framework Core 会自动检查版本属性,如果版本不匹配,则会抛出 DbUpdateConcurrencyException 异常,您可以在捕获该异常后进行处理。
try
{
    // 查询要更新的实体
    var entity = context.Entities.FirstOrDefault(e => e.Id == 1);
    
    // 修改实体的其他属性

    context.SaveChanges(); // 更新实体时进行乐观并发检查
}
catch (DbUpdateConcurrencyException ex)
{
    // 处理并发异常,例如提示用户、日志记录等
}

通过使用乐观并发,Entity Framework Core 可以在并发访问和修改相同数据时提供一种有效的解决方案。

在处理并发冲突时,有时候我们可能希望采用未保存的值来解决冲突。在 Entity Framework Core 中,可以通过捕获 DbUpdateConcurrencyException 异常并采取适当的措施来实现这一点。

以下是在处理并发冲突时采用未保存的值的一般步骤:

try
{
    // 查询要更新的实体
    var entity = context.Entities.FirstOrDefault(e => e.Id == 1);
    
    // 修改实体的其他属性

    context.SaveChanges(); // 更新实体时进行并发检查
}
catch (DbUpdateConcurrencyException ex)
{
    var entry = ex.Entries.Single();
    var databaseValues = entry.GetDatabaseValues();
    var originalValues = entry.OriginalValues;

    // 使用未保存的值来解决并发冲突
    foreach (var property in originalValues.Properties)
    {
        var databaseValue = databaseValues[property];
        var originalValue = originalValues[property];

        // 采用未保存的值来解决冲突
        entry.CurrentValues[property] = originalValue;
    }

    // 重新尝试保存
    context.SaveChanges();
}

在上述代码中,当捕获到 DbUpdateConcurrencyException 异常时,我们通过获取数据库中的当前值和原始值,然后使用未保存的值来解决冲突。我们遍历实体的所有属性,比较数据库值和原始值,然后将未保存的值重新应用到实体的当前值中。

通过采用未保存的值来处理并发冲突,我们可以确保在并发访问和修改相同数据时提供一种有效的解决方案,同时尽量减少冲突和数据丢失的可能性。
4.在代码中模拟并发

    // 查询要更新的实体
    var entity = context.Entities.FirstOrDefault(e => e.Id == 1);
    entity.Name="test1";
    //不需要savechange()就已经保存到数据库了
    context.DataBase.ExecuteSqlInterpolated($"update Entities set Name='test2'");
    context.SaveChanges();

上如代码模拟了两个并发,test2先保存到了数据库,test1执行完savechanes()后才把保存到数据库,应为test2保存到了数据库Version的版本时间戳跟新了,test1还是原来的时间戳,test1保存时和最新的时间戳比较,发现不一致,所以会进入修改并发异常。


http://www.kler.cn/a/147067.html

相关文章:

  • 一些常见网络安全术语
  • Java基础-集合
  • Vue2+ElementUI:用计算属性实现搜索框功能
  • Ubuntu22.04 安装mysql8 无法修改端口及配置的问题 坑啊~~~~
  • “fc-async”提供了基本的异步处理能力
  • 记录配置ubuntu18.04下运行ORBSLAM3的ros接口的过程及执行单目imu模式遇到的问题(详细说明防止忘记)
  • uniapp高德、百度、腾讯地图配置 SHA1
  • C语言第三十四弹--矩形逆置
  • 小航助学题库蓝桥杯题库stem选拔赛(21年3月)(含题库教师学生账号)
  • ElasticSearch之cat anomaly detectors API
  • nodejs+vue+elementui足球篮球联赛系统
  • 【C++】POCO学习总结(六):线程、线程池、同步
  • iview table 默认排序字段不高亮解决办法
  • Elasticsearch:什么是非结构化数据?
  • css实现图片绕中心旋转,鼠标悬浮按钮炫酷展示
  • android 9 adb安装过程学习(三)
  • TS 函数及多态
  • Windows10-用户账户控制、Windows远程桌面
  • 解决:前端js下载文件流出现“未知文件格式”错误
  • C语言重点编程题——11-20
  • Android 编译系统AIDL模块couldn‘t find import for class错误
  • leetcode42接雨水问题
  • Javascript每天一道算法题(十八)——矩阵置零-中等
  • 带你用uniapp从零开发一个仿小米商场_10. 首页开发
  • MATLAB算法实战应用案例精讲-【图像处理】图像增强
  • go 在使用Elasticsearch 聚合查询时 如何设置使用中国时区