确保 Entity Framework 中的并发(金钱)交易?

Ensure concurrent (money) transactions in Entity Framework?

假设我有一个 account_profile table,它有一个类似于账户资金的 Score 字段(数据库类型是 BIGINT(20) 并且 EntityFramework 类型是 long,因为我不需要小数)。现在我有以下功能:

public long ChangeScoreAmount(int userID, long amount)
{
    var profile = this.Entities.account_profile.First(q => q.AccountID == userID);

    profile.Score += amount;

    this.Entities.SaveChanges();

    return profile.Score;
}

不过,我怕ChangeScoreAmount同时调用多次,最后的金额不对。

以下是我目前想到的解决方案:

问题是,我从来没有尝试过对 static 变量加锁,所以我不知道它是否真的安全,是否会发生死锁。此外,如果在此函数之外的其他地方,中途应用对 Score 字段的更改,则可能会很糟糕。

好的,这不再是一个选项,因为我的服务器应用程序将在多个站点上 运行,这意味着无法使用锁定变量

我正在使用 MySQL Community 5.6.24 和 MySQL .NET Connector 6.9.6 以防万一。

注意 我的服务器应用程序可能 运行 连接在多台服务器计算机上。

您可以使用具有可重复读取隔离级别的 sql 事务,而不是锁定应用程序。例如你可以写

public long ChangeScoreAmount(int userID, long amount)
{
    using(var ts = new TransactionScope(TransactionScopeOption.RequiresNew, 
        new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead })
    {
      var profile = this.Entities.account_profile.First(q => q.AccountID == userID);

      profile.Score += amount;

      this.Entities.SaveChanges();

      ts.Complete();

      return profile.Score;
    }    
}

事务保证当您不提交或回滚时,accountprofile 记录不会在数据库中更改。