悲观地锁定进程之间的代码

Pessimistically locking code between processes

我们有以下进程可以修改同一个数据集:

当 Parent/Child 数据集被两个进程同时修改时,推荐的方法是什么来确保我们保持数据完整性(C# Lock 语句将不起作用,因为它的代码 运行 在不同的进程)。

目前他们正在使用 Entity Framework,该过程会将数据集加载到内存中,处理数据,然后保存。问题是数据最初被进程B读取后,可能会被另一个进程A更改​​。

数据在 SQL Azure 数据库中。

我能否在父 table 记录 (Id = XXXX) 上创建一个阻塞事务,这样其他进程只需等待锁被释放。如何最好地做到这一点?

否则,我脑海中浮现出的一些其他想法可能是在父记录上设置一个 "Locked" 字段,或者检查每个子 table 的父 UNION 的 MAX RowVersion (对于父 ID)并在每次更改之前和之后检查此 RowVersion?

sp_getapplock 存储过程似乎正是您所需要的。

当您想要同步需要独占访问数据库的一部分的进程时,它非常有用。

这应该像下面这样。其中 ctxDbContext,并且您要同步的每个进程都使用相同的共享逻辑名称字符串 "MYLOCKNAME",或您想要的任何名称。

using (var tran = ctx.Database.BeginTransaction())
{
    try
    {
        const string lockName = "MYLOCKNAME";

        var resourceParam = new SqlParameter("Resource", SqlDbType.NVarChar, 255) { Value = lockName };
        var lockModeParam = new SqlParameter("LockMode", SqlDbType.NVarChar, 32) { Value = "Transaction" };
        ctx.Database.ExecuteSqlCommand("EXEC sp_getapplock @Resource, @LockMode", resourceParam, lockModeParam);

        // Do stuff with ctx
        // ...

        tran.Commit();
    }
    catch
    {
        tran.Rollback();
    }
}