c# - 在没有数据竞争的情况下转账
问题描述
问题: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 得到不存在的钱。
解决方案
推荐阅读
- java - 如何使用 youtube data api v3 登录
- javascript - 我想要输入文本/javascript,但它因“图像/gif”而失败
- pine-script - 松树:将系列整数转换为整数
- python - 如何通过名称找出正在运行的 python 脚本的 psid?
- python - Protobuf 将 int64 数据类型编码为 json 映射中的字符串
- java - 使用 USB 打印机打印 pdf
- c - 关于 C 练习 6.18-2 的指针,我的解决方案不起作用
- node.js - 用于项目更新的 Angular 预填充表单
- javascript - 为什么history.push 在路由“/”中不起作用?
- php - PHP 64 位连接到 32 位 ODBC 驱动程序