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--处理数据并发问题】的更多相关文章

  1. python导出zabbix数据并发邮件脚本

    Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...

  2. EF|CodeFirst数据并发管理

    在项目开发中,我们有时需要对数据并发请求进行处理.举个简单的例子,比如接单系统中,AB两个客服同时请求处理同一单时,应该只有一单请求是处理成功的,另外一单应当提示客服,此单已经被处理了,不需要再处理. ...

  3. Oracle的数据并发与一致性详解(下)

    上篇介绍了数据并发与一致性的相关概念.以及oracle的事务隔离级别等内容,本篇继续介绍锁机制.自动锁.手动锁.用户自定义锁的相关内容. 请尊重作者劳动成果,转载请标明原文链接: https://ww ...

  4. Oracle的数据并发与一致性详解(上)

    今天想了解下oracle中事务与锁的原理,但百度了半天,发现网上介绍的内容要么太短,要么版本太旧,而且抄袭现象严重,所以干脆查官方帮助文档(oracle 11.2),并将其精华整理成中文,供大家一起学 ...

  5. js获取cookie数据并发送给服务端

    js获取cookie数据并发送给服务端 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  6. ADO.NET 中的数据并发

    当多个用户试图同时修改数据时,需要建立控制机制来防止一个用户的修改对同时操作的其他用户所作的修改产生不利的影响.处理这种情况的系统叫做“并发控制”.并发控制的类型通常,管理数据库中的并发有三种常见的方 ...

  7. sqlserver用timestamp帮助解决数据并发冲突 转【转】

    http://blog.csdn.net/u011014032/article/details/42936783 关于并发请求,网上很多朋友都说的很详细了,我就不在这里献丑了.这里只记录下刚刚完工的那 ...

  8. Entity Framework 数据并发访问错误原因分析与系统架构优化

    博客地址 http://blog.csdn.net/foxdave 本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上 ...

  9. html 获取数据并发送给后端方式

    一.方式一 使用ajax提交 function detailed() { var date = $("#asset_ip").text() $.ajax({ url: " ...

随机推荐

  1. UI2_视图切换ViewController

    // // SubViewController.h // UI2_视图切换 // // Created by zhangxueming on 15/7/3. // Copyright (c) 2015 ...

  2. (转)hessian源码分析(一)------架构

    在计费中心的对外交互这块采用了hessian,有必要对hessian的运行机理和源码做一定的解析. 大致翻了翻源码后,发现hessian的主要结构分客户端与服务端,中间基于http传输.客户端主要做的 ...

  3. 用cudamat做矩阵运算的GPU加速

    1. cudamat简介 cudamat是一个python语言下,利用NVIDIA的cuda sdk 进行矩阵运算加速的库.对于不熟悉cuda编程的程序员来说,这是一个非常方便的GPU加速方案.很多工 ...

  4. Java线程面试题 Top 50(转载)

    原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入Java小组.转载请参见文章末尾的 ...

  5. linux 下权限问题

    linux 系统下的文件权限 drwxr-xr-x. 2 weblogic weblogic 4096 Dec 26 2012 console-ext-rwxr-xr-x. 1 weblogic we ...

  6. 关于java的转义字符

    关于java的转义字符 我们都知道  String s="ad,dfjdlfs,df,s,dfl";              执行 String re[]=s.split(&qu ...

  7. 【风马一族_Android】android的新发现

    Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW");这一段句话.可以调用出系统 ...

  8. Java内存溢出详解

    转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap ...

  9. 身处IT的你对身边人都有哪些影响

    前不久,跟外甥一起吃饭:他明年就要中考了,我就想,这马上就到人生的关键路口了,看他自己对将来有什么想法没:就问了句:勇勇,你以后想学习哪些方面的东西或者想从事什么工作呢?他简单的说了句:我要跟你一样学 ...

  10. mongodb的常用操作(三)

    继续mongodb的学习和总结: 11.mongodb的mapreduce功能 mapreduce可以说是mongodb的一个很强大的功能,可以实现复杂的运算和统计,做一个简要的总结: 假设有user ...