Это должно быть разрешено при использовании Сериализуемой транзакции вместе с подсказкой TABLOCKX
в начальном операторе выбора.TABLOCKX
должен получить эксклюзивную блокировку таблицы, чтобы никто другой не мог использовать эту таблицу, а для Serializable транзакции должно требоваться HOLDLOCK
, что означает, что все блокировки сохраняются до конца транзакции (вы можете использовать HOLDLOCK
напрямую).
Обновление: Я только что протестировал различные сценарии в Management studio, и похоже, что вам не нужно явно использовать сериализуемую транзакцию.Использование TABLOCKX в любой транзакции достаточно.
Имейте в виду, что такой подход может стать большим узким местом, потому что только одна транзакция может работать с такой таблицей = нет параллелизма.Даже если вы читаете и работаете с единственной записью из миллиона, никто не сможет работать с таблицей, пока ваша транзакция не закончится.
Таким образом, команда должна выглядеть следующим образом:
SELECT * FROM Table WITH (TABLOCKX) WHERE ...
ИспользоватьСериализуемая транзакция, которую вы можете использовать SqlTransaction
:
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable);
try
{
...
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
...
}
}
или System.Transactions.TransactionScope
(уровень изоляции по умолчанию должен быть Serializable).
using (TransactionScope scope = new TransactionScope())
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
...
}
scope.Complete();
}