имеется куча потоков, которая вызывает одну и туже хранимку, которая там что-то сложное делает с базой.
вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
вопрос 3: как наилучшим образом бороться, чтобы не растерять алюсы многопоточности? у меня два выхода: 1- блокировать mutex'om момент вызова процедуры; 2-ловить вот это
Transaction (Process ID 140) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
и делать то что говорится, то бишь Rerun the transaction
18.05.06 17:51: Перенесено модератором из '.NET' — AndrewVK
Здравствуйте, lumf, Вы писали:
L>тема достаточно избитая, но все же...
L>имеется куча потоков, которая вызывает одну и туже хранимку, которая там что-то сложное делает с базой.
L>вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
L>вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
L>вопрос 3: как наилучшим образом бороться, чтобы не растерять алюсы многопоточности? у меня два выхода: 1- блокировать mutex'om момент вызова процедуры; 2-ловить вот это
В форум БД, пользоваться поиском, искать статью на RSDN по взаимоблокировкам
Здравствуйте, lumf, Вы писали:
L>тема достаточно избитая, но все же...
L>имеется куча потоков, которая вызывает одну и туже хранимку, которая там что-то сложное делает с базой.
L>вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
L>вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
L>вопрос 3: как наилучшим образом бороться, чтобы не растерять алюсы многопоточности? у меня два выхода: 1- блокировать mutex'om момент вызова процедуры; 2-ловить вот это
L>
L>Transaction (Process ID 140) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
L>
L>и делать то что говорится, то бишь Rerun the transaction
Mutex не поможет если будет запущено несколько приложений, мы устанавливали режим блокировки строки вместо блокировки страницы это уменьшило вероятность deadlocks, а в остальном — в приложении обрабатывали ситуацию и повторяли запрос, вроде работало.
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, lumf, Вы писали:
L>>вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
DAS> нет
L>>вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
DAS> нет
Здравствуйте, SergPas, Вы писали:
SP>Здравствуйте, DemAS, Вы писали:
DAS>>Здравствуйте, lumf, Вы писали:
L>>>вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
DAS>> нет
L>>>вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
DAS>> нет
SP>IMXO — все с точностью наоборот.
Здравствуйте, DemAS, Вы писали: L>>>>вопрос 1: если бы в хранимке была лишь одна инструкция insert возник бы dead lock?
DAS>>> нет
L>>>>вопрос 2: если бы в хранимке была лишь одна инструкция update(причем каждый поток апдейтит уникальную запись) возник бы dead lock?
DAS>>> нет
SP>>IMXO — все с точностью наоборот.
DAS> Опиши, как ты это видишь?
dedlock — это не проблема (нормальная ситуация MSSQL-сервера), тем более не проблема приложения.
Не важно сколько DML-запросов выполняется, если изменяемые данные(ключи, индексы ...)
приходятся на заблокированную страницу (обычно 4K) возникает блокировка — это нормально,
проще провторить запрос и не беспокоиться. Можно бороться другими способами, но IMXO это
только усложнит задачу и снизит производительность.
SP>dedlock — это не проблема (нормальная ситуация MSSQL-сервера)
Блокировка — это не проблема. Deadlock — повод задуматься и сделать так, чтобы не было.
Блокировка, это когда 2 конкурирующих процесса борются за одни ресурсы и при этом процесс 1 ожидает пока процесс 2 освободит ресурс, а 2-ой процесс ожидает 1-ый.
Допустим у нас есть два ресурса А и Б, и два процесса 1 и 2.
1) Процесс 1 блокирует ресурс А
2) Процесс 2 блокирует ресурс Б
3) Процесс 1 хочет заблокировать ресурс Б, но не может и ожидает процесс 2
4) Процесс 2 хочет заблокировать ресурс А, но не может и ожидает процесс 1
Классическая взаимоблокировка.
Как вообще может возникнуть deadlock при работе с одним (и только одним) ресурсом ?
Прошу прощения, читать конечно надо так:
DAS> ВзаимоБлокировка, это когда 2 конкурирующих процесса борются за одни ресурсы и при этом процесс 1 ожидает пока процесс 2 освободит ресурс, а 2-ой процесс ожидает 1-ый.
Здравствуйте, DemAS, Вы писали:
DAS>Здравствуйте, SergPas, Вы писали:
DAS> Допустим у нас есть два ресурса А и Б, и два процесса 1 и 2. DAS> 1) Процесс 1 блокирует ресурс А DAS> 2) Процесс 2 блокирует ресурс Б DAS> 3) Процесс 1 хочет заблокировать ресурс Б, но не может и ожидает процесс 2 DAS> 4) Процесс 2 хочет заблокировать ресурс А, но не может и ожидает процесс 1
DAS> Классическая взаимоблокировка.
DAS> Как вообще может возникнуть deadlock при работе с одним (и только одним) ресурсом ?
Со всем согласен, блокировка возможна — взаимоблокировка нет.
Но в конкретном случае сложно заранее определить из-за какого ресурса возникает "проблема".
У MSSQL при возникновении блокировки (не deadlock) запрос становиться в ожидание в специальную
очередь (размер которой настраивается параметрами сервера), при переполнении очереди происходит эскалация
блокировки со строки до страницы и так до таблицы в целом. После чего вероятность deadlock возрастает.
При возникновении deadlock MSSQL выдергивает запрос из очереди и сообщает об этом приложению и так до тех пор пока
не разрулится ситуация.
Давно это было, я уже всех тонкостей не помню, перешли на Oracle там таких проблем нет.
А за подробностями лучше обратиться на www.sql.ru — там все гораздо подробнее.
Здравствуйте, SergPas, Вы писали:
SP>Со всем согласен, блокировка возможна — взаимоблокировка нет.
Ага. А в исходном сообщении, человек как раз и спрашивал про взаимоблокировку, поэтому я и ответил "нет".
SP>У MSSQL при возникновении блокировки (не deadlock) запрос становиться в ожидание в специальную SP>очередь (размер которой настраивается параметрами сервера), при переполнении очереди происходит эскалация SP>блокировки со строки до страницы и так до таблицы в целом.
Насколько я помню, тут нет никакой очереди. Если менеджеру блокировки для хранения информации о наложенных блокировках требуется более 40% памяти, то он пытается эскалировать блокировки. В случае, если другие строки таблицы заблокированы другим процессом — эскалация не происходит.
SP>После чего вероятность deadlock возрастает.
Да за счет чего она увеличивается то? Мы по прежнему имеем один ресурс — на этот раз таблицу, за которую происходит борьба. Откуда возьмется deadlock ?
SP>При возникновении deadlock MSSQL выдергивает запрос из очереди и сообщает об этом приложению и так до тех пор пока SP>не разрулится ситуация.
При возникновении deadlock сервер стоит граф блокировок и выбирает один из процессов, как кандидат на rollback. После чего второй процесс продолжает свое выполнение.
SP>Давно это было, я уже всех тонкостей не помню, перешли на Oracle там таких проблем нет.
Здравствуйте, DemAS, Вы писали:
DAS> Насколько я помню, тут нет никакой очереди. Если менеджеру блокировки для хранения информации о наложенных блокировках требуется более 40% памяти, то он пытается эскалировать блокировки. В случае, если другие строки таблицы заблокированы другим процессом — эскалация не происходит.
Я имел дело с MSSQL6.5 не знал что все изменилось.
SP>>После чего вероятность deadlock возрастает.
DAS> Да за счет чего она увеличивается то? Мы по прежнему имеем один ресурс — на этот раз таблицу, за которую происходит борьба. Откуда возьмется deadlock ?
Дык, с этой таблицей (другими записями) можер работать кто угодно другой.
SP>>Давно это было, я уже всех тонкостей не помню, перешли на Oracle там таких проблем нет.
DAS> Там есть другие проблемы
Это точно, особенно для разработки клиентских приложений.
Здравствуйте, BlackTigerAP, Вы писали:
BTA>Блокировать надо таблицы. Притом в правильном порядке, едином для всех операций. Тогда dead-lock-ов не будет (почти).
Ну что-ж... И тебе рекомендую почитать статейку по взимоблокировкам.
BTA>Когда пишешь многопользовотельское приложение, нужно ОЧЕНЬ хорошо планировать. Когда многопоточное — планировать ЕЩЕ больше.
BTA>На коленке многопользовательские приложения не собираются и "по книжке" не пишутся.
Вроде трудно не согласиться, но после "блокировать таблицы" как-то выглядит не очень.
Здравствуйте, BlackTigerAP, Вы писали:
DemAS>>> Прям так сразу всю таблицу? Да еще и в многопользовательском приложении?
BTA>Не надо меня прямо так буквально понимать. Ну не всю таблицу, а необходимый кусок. Хотя иногда надо бы и всю таблицу. Зависит от характера изменений.
Не понимаешь ты механизм блокировок MS SQL, а советы даешь. Сколько пишу на MS SQL, ну вот НИ РАЗУ не потребовалось ставить хинт tablock или tablockx. Уровень изоляции транзакций до serializable в нескольких (менее 5) запросах — есть хинты. Вот таким образом и надо работать с блокировками.
SP>dedlock — это не проблема (нормальная ситуация MSSQL-сервера), тем более не проблема приложения.
Что-то путаешь: блокировку и взимоблокировку.
SP>Не важно сколько DML-запросов выполняется, если изменяемые данные(ключи, индексы ...) SP>приходятся на заблокированную страницу (обычно 4K) возникает блокировка — это нормально,
Ну вобще-то 8К
SP>проще провторить запрос и не беспокоиться. Можно бороться другими способами, но IMXO это SP>только усложнит задачу и снизит производительность.
2all: Еще раз: читать статью, а потом с умным видом давать советы
Здравствуйте, SergPas, Вы писали:
SP>Здравствуйте, DemAS, Вы писали:
DAS>> Насколько я помню, тут нет никакой очереди. Если менеджеру блокировки для хранения информации о наложенных блокировках требуется более 40% памяти, то он пытается эскалировать блокировки. В случае, если другие строки таблицы заблокированы другим процессом — эскалация не происходит.
SP>Я имел дело с MSSQL6.5 не знал что все изменилось.
Открою секрет: Windows XP все-таки отличается от Windows 3.1. Впрочем как и MS SQL 2005 отличается от MS SQL 6.5
Здравствуйте, _d_m_, Вы писали:
___>Уровень изоляции транзакций до serializable в нескольких (менее 5) запросах — есть хинты. Вот таким образом и надо работать с блокировками.
И при этом все стоят и нервно курят, пока один человек выполнит свой запрос? А если они только почитать чего-нить хотят, причем совсем не из тех таблиц, которые изменяет работающая в данный момент транзакция?