【问题标题】:Entity Framework: exclusive record update - force to increment current value instead of replacing it实体框架:独占记录更新 - 强制增加当前值而不是替换它
【发布时间】:2013-08-08 14:56:30
【问题描述】:

我正在尝试创建某种金融系统,我想在高并发模式下更新账户余额。当然,我需要独占访问特定帐户记录才能读取实际值并更新它。不幸的是,我无法使用 EF 序列化读取现有记录。 问题:是否可以强制 EF 生成更新,例如:

update MyTable
set Balance=Balance+xxx  //where xxx my balance increment
where ID=yyy

而不是

update MyTable
set Balance=NewValue
where ID=...

还是我错过了其他一些正确的方法?目前我只看到一种可能的解决方案:使用直接 SQL 命令通过单独的连接更新余额,而不与实体框架交互。

如何重现: 我正在创建 ASP.NET 应用程序,每个线程都有自己的 DbContext 来连接到数据库。我的模型非常简化的形式如下:

public class Account{
    public int Id {get; set;}
    public decimal Balance {get; set;}
}
public class Entry {
    public int Id {get; set;}
    public int AccountId {get; set;}
    public decimal Amount {get; set;}
}

在发布条目后,我需要更新帐户余额。我正在使用 JMeter 来模拟多用户站点访问。最简单的测试是在几十个线程中发布相同的金额,然后计算所有帐户的总余额。例如,如果我们有 20 个线程,每个线程有 10 个请求,每个线程的 post amount=50,我们应该得到 10000 作为总余额。 我知道我需要在这里小心处理数据库锁,并且我知道如何在低级别的数据库访问中执行此操作。我只是想找到一种在没有任何外部东西的情况下使用实体框架的方法。我已经和TransactionScope 玩过很多次了,但看起来我不能;无法序列化当前余额值的读取访问。

【问题讨论】:

    标签: asp.net .net sql entity-framework entity-framework-5


    【解决方案1】:

    这听起来像 Entity Framework 是不适合这项工作的工具。它并不意味着完全取代您与数据库的每一次交互。按照你说的做,最好的办法是直接运行 SQL。

    但是,我建议更改您的数据库结构。您说您将有 200 个(20 个线程 * 10 个请求)更新。为什么不做一个活动表。这 200 次更新将转换为 200 次插入到活动表中。无需设置Amount = Amount + 50,只需将50 插入活动表即可。这样就没有任何线程踩到另一个线程的机会。此外,您还可以获得交易历史记录,如果您需要撤销一笔交易,这非常简单。

    编辑

    我刚刚重新阅读了这个问题。看起来你的Entry 表就是我的建议。在这种情况下,数据库规范化表明您应该从 Account 中删除 Balance。当您需要显示时即时计算。

    【讨论】:

      猜你喜欢
      • 2017-05-13
      • 2021-09-21
      • 2019-07-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      相关资源
      最近更新 更多