【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: " ...
随机推荐
- 【转】C#异步编程及其同步机制
C#异步编程及其同步机制 本篇文章涵盖一下几部分内容: 1. 什么是异步编程,为什么会需要异步编程 2. .NET下的异步编程及其发展 3. .NET线程同步机制及线程间数据封送 4. 异步模式 5. ...
- State模式
地铁十字转门 状态迁移表格. 起始状态 触发迁移的事件 终止状态 要执行的动作. Locked Coin UnLocked UnLock UnLocked Pass ...
- ODBC,实现图片循环写入Oracle数据库
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import jav ...
- 8个超炫酷的纯CSS3动画及源码分享
在现代网页中,我们已经越来越习惯使用大量的CSS3元素,而现在的浏览器也基本都支持CSS3,所以很多时候我们不妨思考一下是否可以用纯CSS3制作一些有趣或者实用的网页.本文要分享8个超炫酷的纯CSS3 ...
- Linux系统目录分析
Linux系统目录分析 /bin :系统指令目录(如ls.cp.mv等指令) /dev :系统设备目录 /home :系统用户的家,每一个系统用户都在此目录下有一个自己的家,每次登录时,系统都会自动登 ...
- android网络编程
android的网络编程分为2种:基于socket的,和基于http协议的. 基于socket的用法 服务器端: 先启动一个服务器端的socket ServerSocket svr = new ...
- 简单工厂(Simple Pattern)模式
一.简单工厂(Simple Factory)模式 Simple Factory 模式根据提供给它的数据,返回几个可能类中的一个类的实例.通常它返回的类都有一个公共的父类和公共的方法. Simple F ...
- 《Apache数据传输加密、证书的制作》——涉及HTTPS协议
首先了解http和https: HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议. HTTPS和HTTP的区别: http是超文本传输协议,信息是明 ...
- 使用 Time Machine 恢复 .ssh等隐藏文件夹
重装MAC系统后,要恢复.ssh等文件夹内容,而其在“Finder”中又是默认隐藏的,这时我们可以先在“Finder”中使用“前往文件夹功能…”进入指定文件夹,然后再进入“Time Machine”进 ...
- Java HttpURLConnection 抓取网页内容 解析gzip格式输入流数据并转换为String格式字符串
最近GFW为了刷存在感,搞得大家是头晕眼花,修改hosts 几乎成了每日必备工作. 索性写了一个小程序,给办公室的同事们分享,其中有个内容 就是抓取网络上的hosts,废了一些周折. 我是在一个博客上 ...