The database operation was expected to affect 1 row(s), but actually affected 0 row(s); 解决乐观并发
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); 解决乐观并发
1.乐观并发
EF Core 实现 乐观并发,假定并发冲突相对较少。 与 悲观 方法(即先锁定数据,然后才继续修改数据)不同,乐观并发不需要锁定,而是安排数据修改在保存时失败(如果数据自查询后已更改)。 此并发故障将报告给应用程序,应用程序可能会通过对新数据重试整个操作来相应地处理它。
在 EF Core 中,乐观并发是通过将属性配置为 并发令牌来实现的。 在查询实体时加载和跟踪并发令牌,就像任何其他属性一样。 然后,在 期间 SaveChanges()执行更新或删除操作时,数据库上的并发令牌值与 EF Core 读取的原始值进行比较。
代码触发乐观会如下错误:
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
2.设置乐观锁
我的程序使用EF Core,然后给实体类设置了乐观并发 UseIdentityColumn
public void Configure(EntityTypeBuilder<ChatRecord> builder)
{
//在 PostgreSQL 中,表名以及列名是不区分大小写的。这意味着在数据库中创建表时,无论您是使用大写、小写或混合大小写的名称,最终都会使用相同的名称来访问和操作该表。
//设置表
builder.ToTable("ChatRecord");
//设置表主键
builder.HasKey(e => e.ChatRecordId);
//设置主键自增
builder.Property(e => e.ChatRecordId)
.UseIdentityColumn();
}
3.什么情况下会触发乐观并发
乐观并发允许发生并发冲突,并在并发冲突发生时作出正确反应。 例如,Jane 访问院系编辑页面,将英语系的预算从 350,000.00 美元更改为 0.00 美元。
在 Jane 单击“保存”之前,John 访问了相同页面,并将开始日期字段从 2007/1/9 更改为 2013/1/9。
Jane 单击“保存”后看到更改生效,因为浏览器会显示预算金额为零的“索引”页面。
John 单击“编辑”页面上的“保存”,但页面的预算仍显示为 350,000.00 美元。 接下来的情况取决于并发冲突的处理方式:
跟踪用户已修改的属性,并仅更新数据库中相应的列。
在这种情况下,数据不会丢失。 两个用户更新了不同的属性。 下次有人浏览英语系时,将看到 Jane 和 John 两个人的更改。 这种更新方法可以减少导致数据丢失的冲突数。 这种方法具有一些缺点:
- 无法避免数据丢失,如果对同一属性进行竞争性更改的话。
- 通常不适用于 Web 应用。 它需要维持重要状态,以便跟踪所有提取值和新值。 维持大量状态可能影响应用性能。
- 可能会增加应用复杂性(与实体上的并发检测相比)。
让 John 的更改覆盖 Jane 的更改。
下次有人浏览英语系时,将看到 2013/9/1 和提取的值 350,000.00 美元。 这种方法称为“客户端优先”或“最后一个优先”方案 。 客户端的所有值优先于数据存储的值。 基架代码不处理并发,“客户端优先”方案会自动执行。
阻止在数据库中更新 John 的更改。 应用通常会:
- 显示错误消息。
- 显示数据的当前状态。
- 允许用户重新应用更改。
这称为“存储优先”方案。 数据存储值优先于客户端提交的值。 本教程中使用了“存储优先”方案。 此方法可确保用户在未收到警报时不会覆盖任何更改。
4.解决方案:重写SaveChanges
在 FrameworkDbContext 的DbContext类中重写SaveChanges方法
代码如下:
public override int SaveChanges()
{
var saved = 0;
while (saved !=0) {
try {
base.SaveChanges();
saved++;
}
catch (DbUpdateConcurrencyException ex) {
foreach (var entry in ex.Entries) {
var proposedValues = entry.CurrentValues;
var databaseValues = entry.GetDatabaseValues();
foreach (var property in proposedValues.Properties) {
var proposedValue = proposedValues[property];
var databaseValue = databaseValues[property];
}
// Refresh original values to bypass next concurrency check
entry.OriginalValues.SetValues(databaseValues);
}
}
}
return saved;
}
代码可以在github中查找。我的开源项目修改的类的源码,源码地址:https://github.com/TerraMours/TerraMours_Gpt_Api/blob/main/TerraMours/TerraMours/Framework/Infrastructure/EFCore/FrameworkDbContext.cs
参考资料:https://learn.microsoft.com/zh-cn/ef/core/saving/concurrency?tabs=fluent-api
阅读如遇样式问题,请前往个人博客浏览: https://www.raokun.top
拥抱ChatGPT:https://first.terramours.site
开源项目地址:https://github.com/TerraMours/TerraMours_Gpt_Api
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); 解决乐观并发的更多相关文章
- Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded
asp.net 更新数据时报错:Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data ...
- 记录在EF Core级联更新时出现的错误The database operation was expected to affect 1 row(s), but actually affected 0 row(s) (低级错误导致)
错误提示:The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data ma ...
- one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [3, 1280, 28, 28]], which is output 0 of LeakyReluBackward1, is at version 2;
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace o ...
- Cocos2d-x 3.0 编译出错 解决 error: expected ';' at end of member declaration
近期把项目移植到cocos2d-x 3.0,在整Android编译环境的时候,出现一大堆的编译出错,都是类似"error: expected ';' at end of member dec ...
- Previous operation has not finished; run 'cleanup' if it was interrupted最简单有效的解决方法
今天提交代码报错,看了看提示的错误,百度了一下,发现操作都比较繁琐,所以自己重新给一个最简单有效的. 有的要下载sqlite3.exe,借助它清空本地.svn\wc.db数据库文件里面的operati ...
- Json 文件 : 出现 Expected value at 1:0 问题的解决
只要找一个json在线解析,验证你的json文件格式的正确性,错误可以忽略. 如要消除红叉,关闭Json Validation即可,如下操作:
- EntityFramework Core解决并发详解
前言 对过年已经无感,不过还是有很多闲暇时间来学学东西,这一点是极好的,好了,本节我们来讲讲EntityFramewoek Core中的并发问题. 话题(EntityFramework Core并发) ...
- asp.net core 操作误区
更新时提示数据变化错误 在更新事件中提示下面错误,在网上找了一下,大部分都是说是冲突问题,但是测试时同时只有一个客户端在进行操作,不应该会有冲突问题,后来发现编辑加载时的ID,和更新提交时的ID不同了 ...
- 【ASP.NET Core学习】Entity Framework Core
这里介绍在ASP.NET Core中使用EF Core,这里数据库选的是Sql Server 如何使用Sql Server 添加模型 && 数据库迁移 查询数据 保存数据 如何使用Sq ...
- MySQL入门篇(七)之Xtrabackup备份与恢复
一.Xtrabackup介绍 MySQL冷备.mysqldump.MySQL热拷贝都无法实现对数据库进行增量备份.在实际生产环境中增量备份是非常实用的,如果数据大于50G或100G,存储空间足够的情况 ...
随机推荐
- 2022-01-06:N个结点之间,表世界存在双向通行的道路,里世界存在双向通行的传送门. 若走表世界的道路,花费一分钟. 若走里世界的传送门,不花费时间,但是接下来一分钟不能走传送门. 输入: T为
2022-01-06:N个结点之间,表世界存在双向通行的道路,里世界存在双向通行的传送门. 若走表世界的道路,花费一分钟. 若走里世界的传送门,不花费时间,但是接下来一分钟不能走传送门. 输入: T为 ...
- 【工作随手记】deaklock排查
生产环境当中还没真正遇到过死锁的问题.有些疑似死锁的问题,后来经过排查也只是其它问题导致的.所以通过jstack到底怎样排查死锁问题有点疏忽了.这里作个记录. 模拟一个死锁 顺便复习一下. 死锁的产生 ...
- .Net使用第三方onnx或ModelBuilder轻松接入AI模型
ML.Net - 开源的跨平台机器学习框架 支持CPU/GPU训练 轻松简洁的预测代码 可扩展其他的机器学习平台 跨平台 1.使用Visual Studio的Model Builder训练和使用模型 ...
- CreateProcess error=2, 系统找不到指定的文件。
遇到一个android 配置.gradle时提示CreateProcess error=2, 系统找不到指定的文件 于是百度有很多这类答案,如:干掉NDK 我按照这么做了,最后顽固的bug 并没有理睬 ...
- 【Python&目标识别】调用百度智能云API实现植被识别
百度智能云于2015年正式对外开放运营,以"云智一体"为核心赋能千行百业,致力于为企业和开发者提供全球领先的人工智能.大数据和云计算服务及易用的开发工具.凭借先进的 ...
- [ARM 汇编]进阶篇—存储访问指令—2.3.2 多数据传输指令
在 ARM 汇编中,多数据传输指令用于一次性从存储器中加载多个数据到寄存器组,或将寄存器组中的多个数据存储到存储器.这些指令通常用于高效地处理数组.结构体等数据结构.在本节中,我们将详细介绍 ARM ...
- [MAUI]弧形进度条与弧形滑块的交互实现
@ 目录 弧形基类 定义 绘制弧 弧形进度条(ProgressBar) 添加动画 宽度补偿 文本 弧形滑块(Slider) 创建控制柄 拖动事件处理 项目地址 进度条(ProgressBar)用于展示 ...
- Cause: org.apache.ibatis.builder.BuilderException: Ambiguous collection type for property 'emps'. You must specify 'javaType' or 'resultMap'
错误原因 这个错误通常表示在解析 Mybatis 映射文件(Mapper XML)时出现了问题,可能的原因有两个: 集合属性缺少 javaType 或 resultMap 属性:该错误信息显示了 &q ...
- 数据库系统架构:从HBase到InfluxDB的变革
目录 数据库系统架构:从 HBase 到 InfluxDB 的变革 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境 ...
- MyBatis-plus乐观锁
什么是乐观锁呢?为什么要使用这个功能?这个功能能做什么呢?如何使用这个? 1.乐观锁( Optimistic Locking ) 是相对悲观锁而言的,乐观锁是假设认为数据一般情况下不会造成冲突,所以在 ...