У меня есть рабочая очередь в SQL, управляемая некоторыми службами, которые считывают записи для обработки с помощью READPAST
запросов.SQL Server Read Uncommitted блокирует транзакции
Недавно я добавил пользовательский интерфейс, чтобы проверить статус очереди, который использует READ UNCOMMITTED
Запросы NHibernate на C#. Не совсем важно, чтобы они вернули мне правильные цифры, просто указав, насколько далеко продвинулась обработка.
/* called from a foreach (I know... I could get them all at once with SQL) */
IQuery query = Persistence.CreateQuery(
"select count(qi) from QueueItem qi where qi.Job = :job");
query.SetEntity("job", thisJob);
using(Persistence.ReadUncommitted())
{
return (long)query.UniqueResult();
}
Проблема в том, что эти запросы состояния начали вызывать таймауты. Иногда они терпят неудачу; иногда они вызывают операции очереди.
main MSDN documentation говорит, что все еще может быть блокировка, если я изменю схему, которой я не являюсь.
С другой стороны, Marcel van der Holst, который, по-видимому работает для команды SQL Server Microsoft, says this по этому вопросу (Майкл задает вопрос не мне):
READ UNCOMMITTED
сделки не будут принимать каких-либо блокировок базы данных, но все равно придется читать страницы баз данных для чтения фактических данных. Если другие транзакции записывают эти страницы одновременно, их может быть блокировка между ними. Внутренне в двигателе мы не разрешаем транзакциям читать страницу во время записи (мы используем защелки, чтобы гарантировать это). Если во время ваших больших запросов происходит много транзакций, большое чтение может по-прежнему блокироваться.
Я делаю что-то дико неправильно? Что я должен изменить, чтобы остановить блокировку?
Схема
create table QueueItem(
ID int identity(1,1) not null,
JobID int not null,
PersonID int not null,
DateProcessed datetime null,
Error varchar(max) null,
constraint [PK_QueueItem] primary key nonclustered (ID)
)
alter table QueueItem
add constraint [FK_QueueItemsToJobs] foreign key (JobID)
references Job (ID)
Некластеризованные показатели:
JobID, DateProcessed, PersonID, ID (Non-Unique, Non-Clustered)
DateProcessed, JobID, PersonID (Non-Unique, Non-Clustered)
JobID, ID (Unique, Non-Clustered)
JobID, PersonID, ID (Unique, Non-Clustered)
PersonID, JobID, ID, DateProcessed (Unique, Non-Clustered)
ID (Unique, Non-Clustered)
В практике
Я уменьшил количество прочтений, потому что он не собирается делать вещи медленнее, но я до сих пор интересно, почему может быть блокировка с READ UNCOMMITTED
.
С точки зрения чисто TSQL/запроса я добавляю модификатор «(nolock)» к каждой таблице, находящейся в запросе, но я не уверен, как это сделать через NHibernate. – ganders
Можете ли вы включить определение таблицы? – brian
@brian Вот настройка таблицы. Является ли внешний ключ тем, что меня убивает? – Michael