Параллелизм в EF4 - Как условно создать сущность - PullRequest
2 голосов
/ 27 апреля 2011

Мне нужно иметь возможность создать новую сущность пользователя , только если предоставленная электронная почта уникальна.

Я всегда занимался этим раньше, выполняя простой if (!UserSet.Any(...)) перед моим AddToUserSet(...). Однако это не параллельное решение и оно сломается при большой нагрузке.

Я просматривал транзакции, но, AFAIK, мне нужно было бы также установить UPDLOCK для SELECT, но EF4 не поддерживает это.

Как все остальные справляются с этим?

Ответы [ 2 ]

1 голос
/ 27 апреля 2011

Вы можете принудительно заблокировать, включив SELECT в транзакцию:

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 на все таблицы во всех инструкциях SELECT в транзакция.

1 голос
/ 27 апреля 2011

в дополнение к вашему чеку вы можете добавить уникальное ограничение в поле электронной почты непосредственно в БД

...