2013-08-01 3 views
3

У меня есть рабочая очередь в 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.

+0

С точки зрения чисто TSQL/запроса я добавляю модификатор «(nolock)» к каждой таблице, находящейся в запросе, но я не уверен, как это сделать через NHibernate. – ganders

+0

Можете ли вы включить определение таблицы? – brian

+0

@brian Вот настройка таблицы. Является ли внешний ключ тем, что меня убивает? – Michael

ответ

0

Я не эксперт по NHibernate, но вы должны попытаться добавить NOLOCK в свои статусные запросы; используйте SetLockMode в NHibernate.

  1. Уменьшить количество индексов, выглядит так, как индексируется каждый столбец.
  2. Вы не используете кластерный индекс, добавляете уникальный кластерный индекс в столбцы JobID, ID.
Смежные вопросы