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 ...
随机推荐
- selenium+requests访问微博
import requests from selenium import webdriver from selenium.webdriver.support import expected_condi ...
- 处理springMvc中responsebody返回中文乱码
法一: @RequestMapping(value="/getUsersByPage",produces = public String getUsers 法二:在sprin ...
- 【Tools】ubuntu无法virtualenv创建python虚拟环境的解决
刚有人问我Ubuntu python虚拟环境无法创建问题,报错same file error,防止今后遇到忘记,记录下可能的问题. 1.先在windows上试了下: pip install virtu ...
- Ubuntu Linux 与 Windows 7双系统安装教程(图文)
前期准备: 1. 备份你的重要数据到其他设备上,以防不测2. 准备linux镜像.可以到ubuntu官网下载iso格式的文件.(注意:如果你是双显卡,不要随便下.amd的双显卡请选择含有"a ...
- Linux下的压力测试工具:ab、http_load、webbench、siege
一.ab 1.1 介绍 ab是apache自带的一款功能强大的测试工具. 安装了apache一般就自带了. 1.2 下载 同apache. 1.3 安装 同apache. 1.4 安装结果 ...
- 织梦去除tag标签url中的问号
找到文件 include\taglib\tag.lib.php 大概87行 把 $row['link'] = $cfg_cmsurl."/tags.php?/".urlencod ...
- ZK客户端脚本的简单使用
sh zkCli.sh [-server ip:port] :连接节点zk客户端[-server ip:port 用于连接集群中指定节点的客户端] 1.创建节点 create [-s] [-e] pa ...
- 移动web页面给用户发送邮件的方法
微信商户通有这么一个需求,用户打开H5页面后,引导用户到电脑下载设计资源包,由于各种内部原因,被告知无后台资源支持,自己折腾了一段时间找了下面2个办法,简单做下笔记. 使用mailto功能,让用户自己 ...
- Oracle数据库中SCOTT用户下的默认表
①EMP(雇员表): ②DEPT(部门表): ③BONUS(奖金表): ④SALGRADE(工资等级表):
- Java经典编程题50道之三十九
写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度. public class Example39 { public static void main(String[] a ...