【EntityFramwork--处理数据并发问题】
EntityFramwork--处理数据并发问题时支持乐观并发,即假定最佳场景(这里是指数据在更新过程中没有发生变化)
具体看《Beginning ASP.NET 4.5 Databases》P188-189:
本书源代码下载地址:
http://www.codeplex.com/Download?ProjectName=CommonServiceLocator&DownloadId=45067
以一下是截取源代码的实现Unit of work、并发、事务的BaseRepository:
BaseRepository.cs:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Repository; namespace DataAccess
{
public class s : IDisposable
{
protected IUnitOfWork UnitOfWork { get; set; }
private bool disposed = false; protected StoreEntities Context
{
get { return (EfStoreDataContext)this.UnitOfWork; }
} /// <summary>
/// .ctor
/// </summary>
/// <param name="unitOfWork"></param>
public BaseRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
this.UnitOfWork = unitOfWork;
} public void Save()
{
try
{
using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
this.Context.SaveChanges();
scope.Complete();
}
}
catch (DbUpdateConcurrencyException concurrencyException)
{
concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
throw;
}
} protected virtual DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
{
return this.Context.Set<TEntity>();
} protected virtual void SetEntityState(object entity, EntityState entityState)
{
this.Context.Entry(entity).State = entityState;
} protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.Context.Dispose();
}
}
this.disposed = true;
} public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
---------------------------
(一).事务
38 using(var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
39 {
40 this.Context.SaveChanges();
41 scope.Complete();
42 }
使用事务的目的:在某个场景中,需要更新多个数据上下文实例,并想要把这些更新放在一个事务中。 2.
---------------
(二)并发
44 catch (DbUpdateConcurrencyException concurrencyException)
45 {
46 concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
47 throw;
48 }
EF框架处理并发的方式:
方式1:
让客户端决定状态----让项的原始值设置为从数据库中获取的值:
concurrencyException.Entries.Single().OriginalValues.SetValues(concurrencyException.Entries.Single().GetDatabaseValues());
方式2:
让客户端决定状态----用存储中的值刷新新实体值:
concurrencyException.Entries.Single().Reload(); 方式3:
自定义一种方案,选择合适的选项。 ---------------------
(三)工作单元 Unit of work
EF中的Unit Of Work机制
(假设StoreEntities 实例的变量名为contexDb)
contexDb.Entry(Order).State = System.Data.EntityState.Modified; //
------------------------------------------------
下面代码是设计一个实现了Unit of work机制和Repository模式的具体实现:
56 protected virtual void SetEntityState(object entity, EntityState entityState)
57 {
58 this.Context.Entry(entity).State = entityState;
59 }
this.Context是
19 protected StoreEntities Context
20 {
21 get { return (EfStoreDataContext)this.UnitOfWork; }
22 }
EfStoreDataContext.cs
public class EfStoreDataContext : StoreEntities, IUnitOfWork
{
public new void SaveChanges()
{
base.SaveChanges();
}
}
EF生成的访问数据的DbContext
namespace DataAccess
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Entities; public partial class StoreEntities : DbContext
{
public StoreEntities()
: base("name=StoreEntities")
{
} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
} public DbSet<Contact> Contacts { get; set; }
public DbSet<Order> Orders { get; set; }
}
}
IUnitofWork.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Repository
{
public interface IUnitOfWork
{
void SaveChanges();
}
}
使用了工作单元 (Unit of work)机制的OrderReposiory:
OrderReposiory.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entities;
using Repository; namespace DataAccess.Repositories
{
public class OrderRepository : BaseRepository, IOrderRepository
{ public OrderRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{ } public IEnumerable<Order> GetAllOrders()
{
return this.GetDbSet<Order>();
} public Order GetByOrderId(int orderId)
{
return this.GetDbSet<Order>().Find(orderId);
} public void Create(Order order)
{
this.GetDbSet<Order>().Add(order);
} public void Update(Order order)
{
this.SetEntityState(order, System.Data.EntityState.Modified);
} public void Delete(int orderId)
{
var order = this.GetDbSet<Order>().Find(orderId);
this.GetDbSet<Order>().Remove(order);
}
}
}
根据上面的设计,这行代码:
37 this.SetEntityState(order, System.Data.EntityState.Modified);
最终调用EF框架生成的
public partial class StoreEntities : DbContext
的方法
contexDb.Entry(Order).State = System.Data.EntityState.Modified; //EF中的Unit Of Work机制
假设StoreEntities 实例的变量名为contexDb
【EntityFramwork--处理数据并发问题】的更多相关文章
- python导出zabbix数据并发邮件脚本
Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...
- EF|CodeFirst数据并发管理
在项目开发中,我们有时需要对数据并发请求进行处理.举个简单的例子,比如接单系统中,AB两个客服同时请求处理同一单时,应该只有一单请求是处理成功的,另外一单应当提示客服,此单已经被处理了,不需要再处理. ...
- Oracle的数据并发与一致性详解(下)
上篇介绍了数据并发与一致性的相关概念.以及oracle的事务隔离级别等内容,本篇继续介绍锁机制.自动锁.手动锁.用户自定义锁的相关内容. 请尊重作者劳动成果,转载请标明原文链接: https://ww ...
- Oracle的数据并发与一致性详解(上)
今天想了解下oracle中事务与锁的原理,但百度了半天,发现网上介绍的内容要么太短,要么版本太旧,而且抄袭现象严重,所以干脆查官方帮助文档(oracle 11.2),并将其精华整理成中文,供大家一起学 ...
- js获取cookie数据并发送给服务端
js获取cookie数据并发送给服务端 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- ADO.NET 中的数据并发
当多个用户试图同时修改数据时,需要建立控制机制来防止一个用户的修改对同时操作的其他用户所作的修改产生不利的影响.处理这种情况的系统叫做“并发控制”.并发控制的类型通常,管理数据库中的并发有三种常见的方 ...
- sqlserver用timestamp帮助解决数据并发冲突 转【转】
http://blog.csdn.net/u011014032/article/details/42936783 关于并发请求,网上很多朋友都说的很详细了,我就不在这里献丑了.这里只记录下刚刚完工的那 ...
- Entity Framework 数据并发访问错误原因分析与系统架构优化
博客地址 http://blog.csdn.net/foxdave 本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上 ...
- html 获取数据并发送给后端方式
一.方式一 使用ajax提交 function detailed() { var date = $("#asset_ip").text() $.ajax({ url: " ...
随机推荐
- "Could not load file or assembly 'DTcms.Web.UI' or one of its dependencies. 拒绝访问。" 的解决办法
出现的问题提示如下:
- tomcat的OutOfMemoryError(PermGen space)解决方法
修改TOMCAT_HOME/bin/catalina.bat,在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: set J ...
- 15个web前端的美轮美奂的 jQuery 图片特效
jQuery是一个非常优秀的 JavaScript 框架,使用简单灵活,同时还有许多成熟的插件可供选择.其中,jQuery 最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入各种 ...
- spring IOC经典理解
不多解释,直接上图片!
- 如何更改Json.NET的序列化规则
我想要使序列化出来的JSON都是小写,可以通过建立 LowercaseContractResolver:DefaultContractResolver 来实现, 创建Custom ContractRe ...
- JS增删改HTML表格
要求如下: 写一个html页面,里面有一个表格,储存用户信息,包括:用户名,密码,姓名,邮箱,电话,qq,身份证号. 现在要通过js对表格进行动态的增删改查(只是内存操作即可): 首先,加载页面时用j ...
- brewhome - 第三方包管理工具
最近对移动开发感兴趣,于是乎有了相当正式的理由购买了一台macbook pro 13. 我虽然以前没有使用过mac os,但是上手却很快,这大概跟我最近几年一直在使用linux系统有关吧.我平时上班时 ...
- 我理解的C++虚函数表
今天拜读了陈皓的C++ 虚函数表解析的文章,感觉对C++的继承和多态又有了点认识,这里写下自己的理解.如果哪里不对的,欢迎指正.如果对于C++虚函数表还没了解的话,请先拜读下陈皓的C++ 虚函数表解析 ...
- SignalR 2.0 系列: 开始使用SignalR 2.0
这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第四篇:开始使用SignalR 2.0 原文:Getting S ...
- rinetd 安装使用
1 下载解压: wget http://www.boutell.com/rinetd/http/rinetd.tar.gz tar zxvf rinetd.tar.gz 2 手动建立目录 mkdir ...