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

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

问题描述

我有一个使用实体框架4.0访问的MySQL服务器。在数据库中,我有一个名为 Works 的表,其中有一些。我用Asp.net开发网站。该表可以多一个用户同时使用。这种情况导致错误的问题。



我的代码如下:

  dbEntities myEntity = new dbEntities(); 

var currentWork = myEntity.works.Where(xXx => xXx.RID == 208).FirstOrDefault();
Console.WriteLine(访问工作);

if(currentWork!= null)
{
Console.WriteLine(Access is not null);
currentWork.WordCount + = 5; //默认WordCount为0
Console.WriteLine(Count changed);
myEntity.SaveChanges();
Console.WriteLine(保存更改);
}
Console.WriteLine(Current Count:+ currentWork.WordCount);

如果一个以上的线程访问数据库同时,只有最后的更改保留。



当前输出:



t1:线程一 - t2:线程二 / p>


t1:访问工作



t2:访问工作



t2:访问不为null



t1:访问不为空



t1:计数更改



t2:计数更改



t1:保存更改



t2:保存更改



t1:当前计数:5



t2:当前数量:5


预期输出:


t1:访问工作



t2:访问工作



t2:访问不为空



t1:访问不为空



t1:计数更改



t2:计数更改



t1:保存更改



t2:保存更改



t1:当前计数:5



t2:当前C ount:10


我知道为什么这个问题,因为这个代码不是原子。如何使用原子操作?

解决方案

使用实体框架,您无法使其成为原子操作。您有以下步骤:


  1. 从数据库加载实体

  2. 更改内存中的计数器

  3. 将更改的实体保存到数据库

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



处理这种情况的最佳方法是使用乐观并发。这基本上意味着如果在步骤1中加载实体时计数器不一样,则步骤3中的更改将不会被保存。相反,您会收到一个异常,您可以通过重新加载实体来处理该异常,重新应用更改。



工作流将如下所示:




  • 实体 WordCount 属性必须标记为并发令牌(Code-First的注释或Fluent API)

  • 从数据库加载实体

  • 更改内存计数器

  • 调用 SaveChanges try-catch 中阻止并捕获类型的异常DbUpdateConcurrencyException

  • 如果在数据库中重新加载 catch 块中的实体,则再次应用更改并调用 SaveChanges 再次

  • 重复最后一步,直到不再出现异常



此答案,您可以找到此过程的代码示例(使用 DbContext )。


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.

My code like that:

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.

Current Output:

t1: Thread One - t2: Thread Two

t1: Access work

t2: Access work

t2: Access is not null

t1: Access is not null

t1: Count changed

t2: Count changed

t1: Save changes

t2: Save changes

t1: Current Count: 5

t2: Current Count: 5

Expected Output:

t1: Access work

t2: Access work

t2: Access is not null

t1: Access is not null

t1: Count changed

t2: Count changed

t1: Save changes

t2: Save changes

t1: Current Count: 5

t2: Current Count: 10

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. Load entity from database
  2. Change counter in memory
  3. Save changed entity to database

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

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.

The workflow would look like this:

  • 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

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

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

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