如何在Entity Framework中完全锁定一行

Zap*_*ica 12 c# sql-server entity-framework rowlocking entity-framework-6.1

我正在处理我们处理货币交易的情况.

例如,我有一个用户钱包表,其中包含余额.

UserId; Wallet Id; Balance
Run Code Online (Sandbox Code Playgroud)

现在在我们的网站和Web服务中,每当某个事务发生时,我们需要:

  1. 检查是否有足够的资金可用于执行该交易:
  2. 从余额中扣除交易成本.

如何以及在整个交易期间锁定该行/实体的正确方法是什么?

根据我的阅读,有一些解决方案,其中EF标记一个实体,然后在将其保存回数据库时对该标记进行比较,但是当另一个用户/程序已经编辑了该数量时它又做了什么?

我能用EF实现这个目标吗?如果没有,我有什么其他选择?

调用存储过程可能允许我正确地锁定行,这样当程序A锁定它时,没有其他人可以访问SQL Server中的那一行吗?

Max*_*din 10

EF没有内置的锁定机制,你可能需要使用原始查询

using (var scope = new TransactionScope(...))
{
    using (var context = new YourContext(...))
    {
        var wallet = 
            context.ExecuteStoreQuery<UserWallet>("SELECT UserId, WalletId, Balance FROM UserWallets WITH (UPDLOCK) WHERE ...");

        // your logic

        scope.Complete();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以在实体框架中对事务设置隔离级别,以确保其他人无法更改它:

YourDataContext.Database.BeginTransaction(IsolationLevel.RepeatableRead)
Run Code Online (Sandbox Code Playgroud)

RepeatableRead 摘要:锁定查询中使用的所有数据,防止其他用户更新数据。防止不可重复读取,但仍然可能出现幻像行。