首页 > 解决方案 > 在没有数据竞争的情况下转账

问题描述

问题:Alice(Person 的实例)想向 Bob(Person 的实例)转账 20 美元。

表:

public class Person
{
    public int Id { get; set; }

    public Collection<Account> Accounts { get; set; }
}

public class Account
{
    public int Id { get; set; }
    public int Money { get; set; }

    public int PersonId { get; set; }
    public Person Person { get; set; }
}

当前账户:

爱丽丝:30美元

鲍勃:0美元

服务检查 Alice 是否有足够的钱,然后进行转账。但是当第二次转账同时发生时,问题就会发生,也想转账20美元(例如,双击“转账”按钮)。

代码如下:

int aliceId = 1;
int bobId = 2;
bool sufficientMoney = Accounts.Any(x => x.PersonId == aliceId && x.Money >= 20);

if (sufficientMoney)
{
    Person aliceAccount = Accounts.FirstOrDefault(x => x.PersonId == aliceId);

    Person bobAccount = Accounts.FirstOrDefault(x => x.PersonId == aliceId);

    using (var transaction = context.Database.BeginTransaction())
    {
        aliceAccount.Money -= 20;
        bobAccount.Money += 20;

        transaction.Commit();
    }
}

可能发生从数据库中读取的两次返回 Alice 有足够的钱,第一个请求执行有效的转账,第二个请求随后执行,让 Alice 剩下负数(无效)的钱,而 Bob 得到不存在的钱。

标签: c#sql-serverentity-framework-core

解决方案


推荐阅读