Entity Framework 乐观并发处理
Entity Framework 乐观并发处理
有一段时间没有更新博客了,今天终于有一些时间,和大家讨论一个Entity Framework 乐观并发处理的问题。首先需要说明的是,这里提到的 “并发” 并不是指的多线程处理,也就是笔者这里要讨论的是另外一个问题场景,这个场景描述如下:
1. 系统用户A从数据库中取得一条记录Record-1
2. 系统用户B从数据库中取得同一条记录Record-1
3. 系统用户B修改记录Record-1,并保存到数据库
4. 系统用户A修改记录Record-1,并保存到数据库
这个场景里面的问题是系统用户B对数据路记录Record-1的修改被A的修改冲掉了,这种行为在某些业务场景中是正确的,但是在某些场景中可能会有问题,因为这样的场景中A可能希望感知Record-1的变化,并做出相应的代码策略处理。针对这种场景Entity Framework 专门有一种解决方案,Timestamp或者叫Rowersion,具体实现代码如下, 在需要支持乐观并发的model上增加Timestamp字段,字段的名字叫RowVersion,当然对应的数据库表上也要加上这个字段RowVersion,类型是timestamp, 这样在以上描述的场景发生时,系统就会捕获到相应的异常,从而有机会对这种场景进行相应的业务处理。
如果不喜欢Data Annotation,也可以使用 Fluent api 进行标记,具体代码如下,
modelBuilder.Entity<Department>().Property(p => p.RowVersion).IsRowVersion();
namespace ContosoUniversity.Models
{
public class Department
{
[ConcurrencyCheck]
public int DepartmentID { get; set; } [StringLength(, MinimumLength = )]
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; } [Timestamp]
public byte[] RowVersion { get; set; } public virtual Instructor Administrator { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
}
try
{
db.Entry(departmentToUpdate).OriginalValues["RowVersion"] = rowVersion;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var clientValues = (Department)entry.Entity;
var databaseEntry = entry.GetDatabaseValues();
if (databaseEntry == null)
{
ModelState.AddModelError(string.Empty, "Unable to save changes. The department was deleted by another user.");
}
else
{
var databaseValues = (Department)databaseEntry.ToObject(); if (databaseValues.Name != clientValues.Name)
ModelState.AddModelError("Name", "Current value: "
+ databaseValues.Name);
if (databaseValues.Budget != clientValues.Budget)
ModelState.AddModelError("Budget", "Current value: "
+ String.Format("{0:c}", databaseValues.Budget));
if (databaseValues.StartDate != clientValues.StartDate)
ModelState.AddModelError("StartDate", "Current value: "
+ String.Format("{0:d}", databaseValues.StartDate));
if (databaseValues.InstructorID != clientValues.InstructorID)
ModelState.AddModelError("InstructorID", "Current value: "
+ db.Instructors.Find(databaseValues.InstructorID).FullName);
ModelState.AddModelError(string.Empty, "The record you attempted to edit "
+ "was modified by another user after you got the original value. The "
+ "edit operation was canceled and the current values in the database "
+ "have been displayed. If you still want to edit this record, click "
+ "the Save button again. Otherwise click the Back to List hyperlink.");
departmentToUpdate.RowVersion = databaseValues.RowVersion;
}
}
当然Timestamp字段不是必须单独添加的,也可以使用model上的已有字段,假设这个字段是DepartmentID,我们可以使用ConcurrencyCheck注解进行标记,当然也可是使用Fluent api 进行标记,具体代码如下,
modelBuilder.Entity<Person>().Property(p => p.DepartmentID).IsConcurrencyToken();
总结
本文详细描述了一种Entity Framework 乐观并发处理的解决方案,并且通过Data Annotation和Fluent api 两种方式进行了详细的说明,希望对大家有所帮助。
Entity Framework 乐观并发处理的更多相关文章
- Entity Framework 乐观并发控制
一.背景 我们知道,为了防止并发而出现脏读脏写的情况,可以使用Lock语句关键字,这属于悲观并发控制的一种技术,,但在分布式站点下,锁的作用几乎不存在,因为虽然锁住了A服务器的实例对象,但B服务器上的 ...
- C# Entity Framework并发处理
原网站:C# Entity Framework并发处理 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NE ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
- [转]C#综合揭秘——Entity Framework 并发处理详解
本文转自:http://www.cnblogs.com/leslies2/archive/2012/07/30/2608784.html 引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的 ...
- Entity Framework 并发处理
什么是并发? 并发分悲观并发和乐观并发. 悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修 ...
- 浅析Entity Framework Core中的并发处理
前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core的并发处理方式. 1.常见的并发处 ...
- Entity Framework 并发处理(转)
什么是并发? 并发分悲观并发和乐观并发. 悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修 ...
- Entity Framework Code First实现乐观并发
Entity Framework Code First实现乐观并发 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: h ...
- Programming Entity Framework 翻译(1)-目录
1. Introducing the ADO.NET Entity Framework ado.net entity framework 介绍 1 The Entity Relationship Mo ...
随机推荐
- vue2.0 组织机构树形选择组件(类似elementui <el-transfer> 与 <el-tree> 两个标签的结合)
1. 效果图 2. 实现: 三级(部门或人员的树形选择) 3. 模拟数据说明: fake.js name: 显示的名称(同时也是源码中 for 循环单一的key , 如果真实数据存在名字有重 ...
- VS2012如何调试JS
下面的操作步骤描述了怎样利用vs.net中的调试器来调试javascript: 1,首先,要让你的ie允许调试脚本,具体步骤如下: 打开ie->工具菜单->inter选项->高 ...
- strcpy和strcat易忽略点
首先来看一段C程序: #include <stdio.h> #include <string.h> #include <stdlib.h> void GetMem( ...
- Linux系统下LNMP一键搭建Linux、PHP、MySQL环境(适合新手搭建linux下的web生成环境)
一. 首先要解释一下,什么是LNMP,LNMP起源于LAMP,LAMP是Linux+Apache+Mysql/MariaDB+Perl/PHP/Python的缩写,这里将Web服务端的Apache替换 ...
- 查看Zookeeper服务器状态信息的一些命令
1.Zookeeper服务器当前节点配置信息: echo conf|nc localhost 2181 2.cons:echo cons|nc localhost 2181 输出当前服务器所有客户端连 ...
- Java多维数组各轴长度可以不对齐
- 机器学习策略——DeepLearning.AI课程总结
一.什么是ML策略 假设你正在训练一个分类器,你的系统已经达到了90%准确率,但是对于你的应用程序来说还不够好,此时你有很多的想法去继续改善你的系统: 收集更多训练数据 训练集的多样性不够,收集更多的 ...
- CodeForces-748B
关键在于判断是否能够得到解决办法,我的思路就是用一个数组来记录每个小写字母对应的按键,如果它出现对应两个级以上不同的按键那么就说明不能得出解决办法,直接打印'-1'.如果能够得出解决办法,就扫描一下数 ...
- scrapy 中日志的使用
我在后台调试 在后台调试scrapy spider的时候,总是觉得后台命令窗口 打印的东西太多了不便于观察日志,因此需要一个日志文件记录信息,这样以后会 方便查找问题. 分两种方法吧. 1.简单粗暴. ...
- Service IP 原理 - 每天5分钟玩转 Docker 容器技术(137)
Service Cluster IP 是一个虚拟 IP,是由 Kubernetes 节点上的 iptables 规则管理的. 可以通过 iptables-save 命令打印出当前节点的 iptable ...