Вы можете принудительно заблокировать, включив 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 в
транзакция.