gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 23:58:47 25 4
gpt4 key购买 nike

假设我有一个 account_profile 表,其中有一个类似于账户资金的 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被多次并发调用时,最终的金额不正确。

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

  • ChangeScoreAmount 函数中添加一个带有静态锁定变量的锁,因为类本身可能会在需要时被实例化多次。它看起来像这样:

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

    profile.Score += amount;

    this.Entities.SaveChanges();

    return profile.Score;
    }
    }

问题是,我从未尝试过锁定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 记录不会在数据库中更改。

关于c# - 确保 Entity Framework 中的并发(金钱)交易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30692289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com