原子增量与实体框架 [英] Atomic Increment with Entity Framework

查看:101
本文介绍了原子增量与实体框架的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MySQL服务器,我访问使用实体框架4.0。在数据库中,我有一个名为作品某些统计成表。我开发Web站点Asp.net。此表acccesable一个更多用户同时进行。而这种情况会导致错误的incerement问题。

I have a MySQL Server which I access using Entity Framework 4.0. In the database I have a table called Works into which some counts. I develop web site with Asp.net. This table acccesable one more user same time. And this situation causes wrong incerement problem.

我的code这样的:

dbEntities myEntity = new dbEntities();

var currentWork = myEntity.works.Where(xXx => xXx.RID == 208).FirstOrDefault();
Console.WriteLine("Access work");

if (currentWork != null)
{
    Console.WriteLine("Access is not null");
    currentWork.WordCount += 5;//Default WordCount is 0
    Console.WriteLine("Count changed");
    myEntity.SaveChanges();
    Console.WriteLine("Save changes");
}
Console.WriteLine("Current Count:" + currentWork.WordCount);

如果不是线程访问多一个数据库的同时,只有最后的更改均保持不变。

If one more than thread access the database same time, only last changes remain.

电流输出:

T1:线程一 - T2:螺纹两个

T1:访问工作

T2:访问工作

T2:访问不为空

T1:访问不为空

T1:计数改为

T2:计数改为

T1:保存更改

T2:保存更改

T1:当前计数:5

t1: Current Count: 5

T2:当前计数:5

t2: Current Count: 5

期望输出:

T1:访问工作

T2:访问工作

T2:访问不为空

T1:访问不为空

T1:计数改为

T2:计数改为

T1:保存更改

T2:保存更改

T1:当前计数:5

t1: Current Count: 5

T2:当前计数:10

t2: Current Count: 10

我知道为什么apeear这个问题,因为这code是不是原子。我怎样才能把原子操作?

I know why apeear this problem, because this code is not atomic. How can i turn atomic operation?

推荐答案

通过实体框架,你不能让这个原子操作。你有步骤进行:

With Entity Framework you can't make this an "atomic" operation. You have the steps:


  1. 从数据库中加载实体

  2. 在内存计数器变更

  3. 保存改变实体数据库

在这些步骤之间的另一个客户端可以从仍然有旧值数据库加载的实体。

In between these steps another client can load the entity from the database which still has the old value.

要应对这种情况的最好方法是使用的乐观并发的。它主要是指如果计数器不一样了,这是当你加载在步骤1中的实体相反,你会得到,你可以通过重新加载实体处理异常和步骤3中的改变将不会被保存重新应用更改。

The best way to deal with this situation is to use optimistic concurrency. It basically means that the change in step 3 won't be saved if the counter is not the same anymore that it was when you loaded the entity in step 1. Instead you'll get an exception that you can handle by reloading the entity and reapplying the change.

工作流程是这样的:


  • 工作实体 WORDCOUNT 属性必须被标记为并发令牌(注释或万一流利的API $的C $ C-前)

  • 从数据库中加载实体

  • 在内存计数器变更

  • 呼叫的SaveChanges 的try-catch 类型的块,并捕获异常 DbUpdateConcurrencyException

  • 如果发生异常重装在抓实体块从数据库中,再次申请变更并调用的SaveChanges 再次

  • 重复最后一步,直到也不例外发生了

  • In the Work entity the WordCount property must be marked as a concurrency token (annotations or Fluent API in case of Code-First)
  • Load entity from database
  • Change counter in memory
  • Call SaveChanges in a try-catch block and catch exceptions of type DbUpdateConcurrencyException
  • If an exception occurs reload the entity in the catch block from the database, apply the change again and call SaveChanges again
  • Repeat the last step until no exception occurs anymore

这个答案你可以找到这个程序一个code为例(使用的DbContext )。

In this answer you can find an code example for this procedure (using DbContext).

这篇关于原子增量与实体框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆