Нулевая мертвая блокировка SQL дизайном - какие-либо шаблоны кодирования?

После быстрого просмотра ссылки я могу наблюдать std :: vector, std :: move, ...

Кажется, код содержит c ++.

Вот одно из определений макроса TRY: http://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=gdb/common/common-exceptions .h; ПП = e3624a40aeb31065c968d0d3a1d55fdf8e8a4e3c # l246

31
задан Joannes Vermorel 21 September 2008 в 18:51
поделиться

9 ответов

Написание защищенного от мертвой блокировки кода действительно трудно. Даже когда Вы получаете доступ к таблицам в том же порядке, можно все еще получить мертвые блокировки [1]. Я записал сообщение на моем блоге , который уточняет посредством некоторых подходов, которые помогут Вам избежать и разрешить ситуации с мертвой блокировкой.

, Если Вы хотите удостовериться, два оператора/транзакции никогда не будут заходить в тупик, можно быть в состоянии достигнуть его путем наблюдения, какие блокировки каждый оператор использует использование системная хранимая процедура sp_lock . Чтобы сделать это, необходимо или быть очень быстрыми или использовать открытую транзакцию с подсказкой holdlock.

<час>

Примечания:

  1. Любой оператор SELECT, для которого нужна больше чем одна блокировка сразу, может зайти в тупик против разумно разработанной транзакции, которая захватывает блокировки в обратном порядке.
21
ответ дан 27 November 2019 в 22:32
поделиться

Быстрый ответ не, нет никакой гарантируемой техники.

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

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

0
ответ дан 27 November 2019 в 22:32
поделиться

Не прямой ответ на Ваш вопрос, но пища для размышления:

http://en.wikipedia.org/wiki/Dining_philosophers_problem

"Проблемой философов Dining" является старый мысленный эксперимент для исследования проблемы мертвой блокировки. Чтение об этом могло бы помочь Вам найти решение своего конкретного обстоятельства.

0
ответ дан 27 November 2019 в 22:32
поделиться

Нулевые мертвые блокировки являются в основном невероятно дорогостоящей проблемой в общем случае, потому что необходимо знать весь tables/obj, который Вы собираетесь считать и изменить для каждой рабочей транзакции (это включает, ВЫБИРАЕТ). Общую философию называют , заказал строгую двухфазную блокировку (чтобы не быть перепутанным с двухфазной фиксацией) ( http://en.wikipedia.org/wiki/Two_phase_locking ; даже 2PL не делает гарантия никакие мертвые блокировки)

Очень немногие, DBMS на самом деле реализует строгую 2PL из-за крупной производительности, поражает такую вещь причины (нет никаких бесплатных ланчей), в то время как все Ваши транзакции ждут даже простые операторы SELECT, которые будут выполняться.

Так или иначе, если это - что-то, которое Вы действительно интересуетесь, смотрите на SET ISOLATION LEVEL в SQL Server. Можно настроить это по мере необходимости. http://en.wikipedia.org/wiki/Isolation_level

Для большего количества информации, посмотрите Википедию на Сериализуемости: http://en.wikipedia.org/wiki/Serializability

, Который сказал - большая аналогия похожа на изменения исходного кода: регистрация рано и часто. Сохраните свои транзакции маленькими (в # SQL-операторов, # измененных строк) и быстрый (стена показывают время, помогает избежать коллизий с другими). Это может быть хорошо и привести в порядок, чтобы сделать МНОГО вещей в единственной транзакции - и в целом я соглашаюсь с той философией - но если Вы испытываете много мертвых блокировок, можно разбить сделку в меньшие и затем проверить их состояние в приложение, как Вы проходите. TRAN 1 - ХОРОШО Y/N? Если Y, отправьте TRAN 2 - хорошо Y/N? и т.д. и т.д.

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

13
ответ дан 27 November 2019 в 22:32
поделиться

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

Общие ответы для сокращения возможностей мертвой блокировки:

  1. Основная оптимизация запросов (надлежащее индексное использование) горячая точка avoidanant дизайн, держите транзакции в течение самых коротких времен... и т.д.

  2. , Когда возможный набор разумные тайм-ауты запроса так, чтобы, если мертвая блокировка должна произойти, это самоочистилось после периода тайм-аута, истекает.

  3. Мертвые блокировки в MSSQL часто происходят из-за его модели параллелизма чтения по умолчанию, таким образом, его очень важные для не зависимости от него - предполагают, что Oracle разрабатывает MVCC во всех проектах. Используйте изоляцию снимка или если возможный ЧТЕНИЕ ОТМЕНИЛО ФИКСАЦИЮ уровня изоляции.

3
ответ дан 27 November 2019 в 22:32
поделиться

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

Другой прохладный прием должен объединить 2 sql оператора в том каждый раз, когда Вы можете. Отдельные операторы являются всегда транзакционными. Например, используйте "ОБНОВЛЕНИЕ... ВЫБЕРИТЕ", Или "ВСТАВЛЯЮТ... ВЫБЕРИТЕ", используйте "@@ ОШИБКА" и "@@ ROWCOUNT" вместо "ИЗБРАННОГО КОЛИЧЕСТВА" или, "ЕСЛИ (СУЩЕСТВУЕТ...)"

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

1
ответ дан 27 November 2019 в 22:32
поделиться

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

1
ответ дан 27 November 2019 в 22:32
поделиться

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

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

Тот способ, которым Вы изолируете операции, которые могут блокировки причины (к определенным хранимым процедурам) и вынимать "простые чтения" из "цикла блокировки".

1
ответ дан 27 November 2019 в 22:32
поделиться

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

1
ответ дан 27 November 2019 в 22:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: