Невозможно использовать READPAST в режиме изоляции снимков - PullRequest
3 голосов
/ 14 апреля 2010

У меня есть процесс, который вызывается из нескольких потоков, который выполняет следующее:

  1. Начать транзакцию
  2. Выберите единицу работы из рабочего стола, найдя следующую строку, где IsProcessed=0 с подсказками (UPDLOCK, HOLDLOCK, READPAST)
  3. Обработка единицы работы (хранимые процедуры на C # и SQL)
  4. Совершить транзакцию

Идея этого состоит в том, что поток погружается в пул для «следующего» фрагмента работы и обрабатывает его, а блокировки существуют для того, чтобы один фрагмент работы не обрабатывался дважды. (порядок не имеет значения).

Все это прекрасно работало в течение нескольких месяцев. До сегодняшнего дня, когда я осознал, что, несмотря на включение изоляции моментальных снимков и установление по умолчанию на уровне базы данных, фактический код создания транзакции вручную устанавливал уровень изоляции «ReadCommitted».

Я должным образом изменил это на «Снимок», и, конечно же, сразу же получил следующее сообщение:

Вы можете указать блокировку READPAST только в READ COMMITTED или REPEATABLE READ

Основная причина блокировки строки состояла в том, чтобы «пометить строку» таким образом, чтобы «метка» была удалена, когда транзакция, которая применила метку, была зафиксирована, и блокировка казалась лучшим способом сделать это. , поскольку эта таблица не читается иначе, кроме как этими потоками. Если бы я использовал флаг IsProcessed в качестве блокировки, то, вероятно, мне нужно было бы сначала выполнить обновление, а затем выбрать только что обновленную строку, но мне нужно было бы использовать флаг NOLOCK, чтобы узнать, установил ли какой-либо другой поток флаг на ряд.

Все звучит немного грязно. Самым простым вариантом было бы вообще отказаться от режима изоляции моментальных снимков, но дизайн шага № 3 требует этого.

Какие-нибудь яркие идеи о том, как лучше решить эту проблему?

1 Ответ

1 голос
/ 23 июля 2010

изменить уровень изоляции конкретной транзакции на нечто иное, чем зафиксированное чтение по умолчанию (которое в вашем случае вы по умолчанию вели в режиме моментального снимка). Затем вы можете оставить другую работу в базе данных в моментальном снимке, но этот конкретный рабочий процесс в вашем коде будет отличаться от моментального снимка.

...