具有entity framework的primefaces增量

我有一个使用Entity Framework 4.0访问的MySQL服务器。 在数据库中,我有一个名为Works的表,其中有些计数。 我用Asp.net开发网站。 该表可以在同一时间再次使用。 而这种情况会导致错误的输入问题。

我的代码是这样的:

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); 

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

电流输出:

t1:线程一 – t2:线程二

t1:访问工作

t2:访问工作

t2:访问不为空

t1:访问不为空

t1:计数已更改

t2:计数已更改

t1:保存更改

t2:保存更改

t1:当前计数:5

t2:当前计数:5

预期产出:

t1:访问工作

t2:访问工作

t2:访问不为空

t1:访问不为空

t1:计数已更改

t2:计数已更改

t1:保存更改

t2:保存更改

t1:当前计数:5

t2:当前计数:10

我知道为什么会遇到这个问题,因为这段代码不是primefaces的。 我怎么能变成primefaces操作?

使用Entity Framework,您无法使其成为“primefaces”操作。 你有以下步骤:

  1. 从数据库加载实体
  2. 在内存中更改计数器
  3. 将更改的实体保存到数据库

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

处理这种情况的最佳方法是使用乐观并发 。 它基本上意味着如果计数器不再与您在步骤1中加载实体时的计数器不同,则不会保存步骤3中的更改。相反,您将获得一个可以通过重新加载实体来处理的exception,重新应用这一变化。

工作流程如下所示:

  • Work实体中,必须将WordCount属性标记为并发令牌(如果是Code-First, WordCount注释或Fluent API)
  • 从数据库加载实体
  • 在内存中更改计数器
  • try-catch块中调用SaveChanges并捕获DbUpdateConcurrencyException类型的DbUpdateConcurrencyException
  • 如果发生exception,则从数据库重新加载catch块中的实体,再次应用更改并再次调用SaveChanges
  • 重复最后一步,直到不再发生exception

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

如果您在单个流程中托管您的网站,则下一种方式将起作用(它不适用于Web场或Web gardsen):

  private static readonly Locker = new object(); void Foo() { lock(Locker) { 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); } } 

你还能做什么,是通过ObjectContext使用原始SQL查询:

  if (currentWork != null) { Console.WriteLine("Access is not null"); myEntity.ExecuteStoredCommand("UPDATE works SET WordCount = WordCount + 5 WHERE RID = @rid", new MySqlParameter("@rid", MySqlDbType.Int32){Value = 208) Console.WriteLine("Count changed"); } var record = myEntity.works.FirstOrDefault(xXx => xXx.RID == 208); if(record != null) Console.WriteLine("Current Count:" + record .WordCount);