问题:EF Core 不引入锁,高并发场景 ExecuteSqlRawAsync("UPDATE Users SET Balance = Balance + {0} WHERE UserId = {1}");后如何获取 Updated 后的值?
背景:
用于余额变动记录。再查一遍肯定不行,极端情况下一个用户会同时发 10000 个下单请求(客户端随硬件交付,没有升级功能,无法更新),这样不加锁余额变动记录就不准了。加锁的话性能太差了。
SELECT Balance, version FROM Users WHERE UserId = {userId}; UPDATE Users SET Balance = Balance + {amount}, version=version+1 WHERE UserId = {userId} AND version={version}; 成功 return Balance + amount;
SELECT Balance FROM Users WHERE UserId = {userId};
UPDATE Users SET Balance = Balance + {amount} WHERE UserId = {userId};
update 和返回最新值
---
2. 引入 version ,乐观锁自旋
2.1 select version;
2.2 update version=version+1 where version = {old_version}
如果 update 成功,说明 select -》 update 之间没有修改,update 成功,新旧值
如果 失败,重复 2.1-2.2 并引入随机等待
---
3. select * for update 提前加锁
然后 UPDATE Users SET Balance = Balance + {0} WHERE UserId = {1}
再次 select 得到最新值
在同一个事务
拿到之后先不管.
然后 return balance + amount;