2009-05-11 3 views
7

У меня есть приложение VB6 для доступа к одной таблице на сервере MSSQL2000 через ADO. Я использую доступ только для чтения (adOpenStatic, adLockReadOnly). В сети есть другие приложения, которые вносят изменения в таблицу.Можно ли создать тупик с доступом только для чтения?

По какой-то причине я получаю ошибки относительно того, что мое приложение выбрано как жертва взаимоблокировки.

Я действительно смущен: почему может быть тупик, когда я просто читаю из одной таблицы? Я ожидал бы отсрочки из-за написания других приложений, но не в тупике ...

Может кто-то пролить свет на это?

ОБНОВЛЕНИЕ: 2009-06-15 Меня все еще интересует решение этой проблемы. Поэтому я обеспечиваю больше информации:

  • Это не имеет никакого значения, если я выбираю adOpenForwardOnly или adOpenStatic
  • Это не имеет никакого значения, если позиция курсора находится клиент или сервер.
+2

Надеюсь, вы уже научились тому, что READ может определенно затормозить, многие ответы указали, как это происходит. Теперь вам нужно сделать домашнее задание и предоставить остальную информацию, т.е. который блокирует * с * и тупиковый график. –

+0

К сожалению, я могу только воспроизвести проблему на производственной системе, поэтому я должен ее замедлить и ничего не пихать. Кроме того, я могу только добраться до сервера через странную комбинацию VPN/VNC/Remote Desktop/Custom file transfer tool (не спрашивать), поэтому даже одна проверка или копирование нового исполняемого файла занимает много времени. –

ответ

12

Это возможно для одного ЗЕЬЕСТА взаимоблокировки против одного UPDATE или DELETE заявления в связи с наличием некластерного индекса, рассмотрит follwing сценария:

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

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

Вы можете найти более подробную информацию об этом (и других) типа тупика в статье Q169960 Microsoft KB (http://support.microsoft.com/kb/q169960/)

Также вы можете посмотреть на Google о том, как получить информацию тупиковый след (следы флаг 1222) - это будет отчет о том, какие именно SQL-запросы противоречат объектам всякий раз, когда возникает тупиковая ситуация. Это довольно приличный ищет статью - http://blogs.msdn.com/bartd/archive/2006/09/09/747119.aspx

+0

Я понимаю, что флаги трассировки глобальны, т. Е. Они влияют на каждое соединение. Поскольку проблема возникает только на рабочем сервере, я должен ждать временного кадра, где я могу это сделать, не рискуя каких-либо проблем. –

+0

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

-1

Не так ли?

Другие приложения: Написать в таблице (приобрести блокировку записи на столе)

Ваше приложение: Чтение из таблицы (получить блокировку чтения таблицы, не может из-за блокировка записи).

+0

В моем опыте, который только блокировал бы мое приложение и в конечном итоге создавал тайм-аут –

+1

Не использовал его сам, но, очевидно, флаг трассировки 1204 на SQL-сервере поможет вам определить, где происходит тупиковая ситуация. См. Http://msdn.microsoft.com/en-us/library/ms178104.aspx –

-1

Это зависит от поведения приложения. ваше приложение может с уверенностью ждать на другом, чтобы освободить ресурсы.

+0

Да, это было бы нормальное поведение, которое я наблюдал во многих других приложениях: блокирование и, возможно, таймаут. –

0

Считывание может по-прежнему включать блокировки, чтобы БД обеспечивала, что запись не выполняется в середине неаммического чтения. Другими словами, блокировка чтения гарантирует, что вы получите точный согласованный снимок любых данных, которые вы выбираете.

-1

Тупик относится к условию, когда два или более процесса ждут друг друга, чтобы освободить ресурс, или более двух процессов ждут ресурсов в круговой цепочке. Конечно, вы можете создать тупик с доступом только для чтения, потому что чтение НЕ будет ждать.

Существует хорошее объяснение об условиях тупиковых на wikipedia

+1

«Конечно, вы можете создать тупик с доступом только для чтения, потому что чтение НЕ будет ждать» - это не имеет для меня смысла. –

0

ли вы получите такое же поведение с adOpenForwardOnly?

Возможно, вы захотите проверить, что ваша статистика SQL Server обновлена. Или вы можете заставить своего DBA восстановить все индексы. Многие проблемы с блокировкой связаны с устаревшей статистикой/индексами.

+0

Я не могу воспроизвести проблему по своему усмотрению, мне нужно подождать и посмотреть ... –

+0

Это не имеет значения :( –

+0

... и вы проверили, что все индексы/статистика в актуальном состоянии? –

3

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

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

  1. вы берете общую блокировку по ресурсной
  2. Другой процесс занимает монопольную блокировку ресурса B
  3. Другой процесс пытается взять эксклюзивную блокировку ресурса А и блоки ожидая, когда вы отпустите свою общую блокировку на A.
  4. Вы пытаетесь использовать общую блокировку ресурса B и блокируете ожидание того, что другой процесс освободит свою исключительную блокировку на B, за исключением того, что вы сейчас находитесь в ситуации взаимоблокировки , который идентифицируется сервером, и он выбирает процесс для уничтожения.

N.B. тупики могут иметь больше игроков, чем просто 2. Иногда есть целая цепь переплетенных действий, которая приводит к тупиковой ситуации, но принцип тот же.

Часто, если несколько приложений обращаются к одной и той же базе данных, есть администратор базы данных, который управляет всем доступом через хранимые процедуры, поэтому он может гарантировать, что ресурсы всегда заблокированы в том же порядке. Если вы не в такой ситуации, а другие приложения используют специальные SQL-инструкции, вам нужно будет проверить их код, чтобы узнать, могут ли они конфликтуют с вашим приложением так, как я описал. Это не похоже на забаву.

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

 Смежные вопросы

  • Нет связанных вопросов^_^