2

我正在处理一个有趣的场景。

我正在使用 EntityFramework 将(插入/更新)保存到多线程环境中的 SQL 数据库中。问题是我需要访问数据库以查看是否已经创建了具有特定键的寄存器以设置字段值(正在执行),或者设置不同的值(待定)是新的。这些寄存器由唯一的 guid 标识。

我已经通过设置锁解决了这个问题,因为我知道实体不会出现在任何其他进程中,换句话说,我在不同的进程中不会有相同的 guid,它似乎工作正常。它看起来像这样:

static readonly object LockableObject = new object();
static void SaveElement(Entity e)
{
       lock(LockableObject)
       {
           Entity e2 = Repository.FindByKey(e);
           if (e2 != null)
           {
               Repository.Insert(e2);
           }
           else
           {
               Repository.Update(e2);
           }
       }
}

但这意味着当我要保存大量请求时,它们将排队。

我想知道是否有类似的东西(请把它当作一个想法):

static void SaveElement(Entity e)
{
       (using ThisWouldBeAClassToProtectBasedOnACondition protector = new ThisWouldBeAClassToProtectBasedOnACondition(e => e.UniqueId)
       {
           Entity e2 = Repository.FindByKey(e);
           if (e2 != null)
           {
               Repository.Insert(e2);
           }
           else
           {
               Repository.Update(e2);
           }
       }
}

这个想法将拥有一种基于条件保护的保护,因此每个实体 e 将拥有基于 e.UniqueId 属性的自己的锁。

任何想法?

4

2 回答 2

1

Don't use application-locks where database transactions or constraints are needed.

The use of a lock to prevent duplicate entries in a database is not a good idea. It limits the scalability of your application be forcing only a single instance to ever exist that can add or update such records. Or worse, someone will eventually try to scale the application to multiple processes or servers and it will cause data corruption (since locks are local to a single process).

What you should consider instead is using a combination of unique constraints in the database and transactions to ensure that no two attempts to add the same entry can both succeed. One will succeed - the other will be forced to rollback.

于 2010-05-26T16:20:07.253 回答
0

This might work for you, you can just lock on the instance of e:

   lock(e)
   {
       Entity e2 = Repository.FindByKey(e);
       if (e2 != null)
       {
           Repository.Insert(e2);
       }
       else
       {
           Repository.Update(e2);
       }
   }
于 2010-05-26T16:19:38.047 回答