我需要能够创建一个新的用户实体 除非 提供的电子邮件是唯一的。

我一直以前通过执行简单来处理此操作 if (!UserSet.Any(...)) 在我之前 AddToUserSet(...). 。但是,这不是并发的解决方案,并且会在沉重的负载下破裂。

我一直在研究交易,但是AFAIK也需要在SELECT上设置一个Updlock,但是EF4不支持这一点。

其他所有人如何处理?

有帮助吗?

解决方案

您可以通过在交易中进行选择来强制锁定:

using (var scope = new TransactionScope())
{
    // Create context
    // Check non existing email
    // Insert user
    // Save changes
}

这将使用可序列化的交易,如果您需要并发解决方案以插入 - Updlock不足以确保在交易过程中不会添加新记录。

这可能是非常糟糕的瓶颈,所以我同意@paolo:只需将唯一的约束放在数据库中,并在插入过程中捕获异常,如果电子邮件不是唯一的。

可序列的交易 在线书籍:

指定以下内容:

    Statements cannot read data that has been modified but not yet  
    committed by other transactions.

    No other transactions can modify data that has been read by the  
    current transaction until the current transaction completes.

    Other transactions cannot insert new rows with key values that
    would fall in the range of keys read by any statements in the current
    transaction until the current transaction completes.

范围锁放置在与交易中执行的每个语句的搜索条件相匹配的键值范围内。这会阻止其他交易更新或插入将有资格获得当前事务执行的任何语句的行。这意味着,如果第二次执行交易中的任何语句,他们将读取相同的行。保留范围锁,直到交易完成为止。这是对隔离级别的最限制,因为它锁定了整个钥匙范围,并保留锁直到交易完成。因为并发较低,因此仅在必要时才使用此选项。此选项在交易中所有选择语句中的所有表中都具有与设置holdlock相同的效果。

其他提示

除支票外,您还可以添加 独特的约束 直接在DB上的电子邮件字段上

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top