powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ох уж эти блокировки
11 сообщений из 11, страница 1 из 1
Ох уж эти блокировки
    #32022749
Screem6
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Господа, может что посоветуете. Есть ПО работающее с SQL базой, причем очень активно (постоянные обновлени таблиц с 70 тыс записями), ПО работает через BDE и ODBC. Первоначально были блокировки - постоянные, причем даже на два запроса SELECT ! Затем программеры не долго думая поставили в запросы UPDATE TABLOCKX, что все замедлило, но тогда решили и так пойдет, теперь они добавили новые функции очень ресурсоемкие и время ответа на запрос резко возросло, средний запрос 30-50 сек !!! Сервер не плохой, RAID контроллер, необходимые индексы есть... можно ли еще что "подкрутить" в настройках SQL или это все же ПО кривое, а может все дело в BDE?

Спасибо всем
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022755
Replicant
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не думаю, что дело в BDE или в настройках SQL Serverа (раз раньше всё работало нормально).
Нельзя также сказать нужна там или нет эта монопольная(эксклюзивная) блокировка,
но то что она всё "тормозит" - это 100%

А что говорят сами разработчики по поводу "улучшения" производительности?
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022758
Похоже, мало, что можно сделать. Так уж написано приложение.
Так как используются громадные транзакции, то должно полегчать, если файл журнала транзакций вынести на отдельный физический диск (лучше зеркало, RAID для него не нужен).
Также можно существенно облегчить ситуацию (щас меня ChA запинает за такое предложение ), если переорганизовать работу таким образом: изменения производить в одной базе, а читать из другой. Между ними, есно, периодическая синхронизация.

Если у вас размер страйпа на raid-массиве 4-8кб, то увеличив этот размер до 64кб, производительность может увеличиться на порядок (а может и не увеличиться совсем в вашей конкретной ситуации)
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022776
Все некритичные SELECT переписал WITH(NOLOCK), а все INSERT, UPDATE WITH(ROWLOCK). Проблему deadlock сняло.

Ещё использую вот такой код:

unit mtoADOSupport;

interface

uses
Classes,
ADODB;

type
(*
* These components based on Tolik Tentser code pie (tt@katren.ru)
* This code fixes multithreading deadlock issue.
*)

TttADOQuery = class(TADOQuery)
protected
procedure InternalOpen; override;
public
constructor Create(AOwner: TComponent); override;
end;

TttADODataSet = class(TADODataSet)
protected
procedure InternalOpen; override;
public
constructor Create(AOwner: TComponent); override;
end;

implementation

uses
SysUtils;

{ TttADOQuery }

constructor TttADOQuery.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;

procedure TttADOQuery.InternalOpen;
var
I, Attempt: Integer;
DeadLock: Boolean;
Err: Errors;
begin
Attempt := 0;
while TRUE do
begin
try
inherited;
except
on E: Exception do
begin
DeadLock := FALSE;
Err := Connection.Errors;
for I := Err.Count-1 downto 0 do
// Åñëè îøèáêà 1205 - Deadlock - ïîâòîðÿåì îïåðàöèþ
if Err .NativeError = 1205 then
begin
DeadLock := TRUE;
Inc(Attempt);
Break;
end;
if DeadLock and (Attempt < 3) then
Continue
else
raise;
end;
end;
Break;
end;
end;

{ TttADODataSet }

constructor TttADODataSet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;

procedure TttADODataSet.InternalOpen;
var
I, Attempt: Integer;
DeadLock: Boolean;
Err: Errors;
begin
Attempt := 0;
while TRUE do
begin
try
inherited;
except
on E: Exception do
begin
DeadLock := FALSE;
Err := Connection.Errors;
for I := Err.Count-1 downto 0 do
// Åñëè îøèáêà 1205 - Deadlock - ïîâòîðÿåì îïåðàöèþ
if Err.NativeError = 1205 then
begin
DeadLock := TRUE;
Inc(Attempt);
Break;
end;
if DeadLock and (Attempt < 3) then
Continue
else
raise;
end;
end;
Break;
end;
end;

end.
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022782
Естественно, всё вышесказанное следуюет применять вкупе с иными техниками. Так, практически все вставки и обновления бизнес-объектов у меня работают через хранимые процедуры. Соответственно, минимизировано количество триггеров. Также надо с умом пользоваться ограничениями (constraints). а блокировки типа tablock - практически смертельно для рабочего oltp-сервера.
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022790
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как я понимаю, проблема проистекает от не очень удачного применения не очень удачного метода разрешения дедлоков. Когда объектов очень много, скрипты сложные, вероятность дедлоков возрастает. Происходят дедлоки обычно потому, что:
а) Транзакции блокируют ресурсы не одномоментно, а последовательно
б) Последовательность блокировок ресурсов в разных транзакциях может привести к блокировке разных ресурсов одновременно несколькими транзакциями и запроса блокировки ресурсов, занятых другими транзакциями, которые в свою очередь запрашивают ресурсы, уже заблокированные в первой транзакции.
Дедлок - это замкнутый круг, бороться с которым можно двумя способами:
1. Откатить одну из транзакций, вошедшую в этот замкнутый круг (что принудительно и делает встроенная в SQL сервер искалка дедлоков).
2. Не допустить замыкания круга и исключить саму вероятность выполнения последовательности блокировок в разных транзакциях, которые могут приветси к взаимным блокировкам.
Способ 1 мало кому нравится по двум причинам. Во-первых, дедлок обнаруживается обычно не сразу. На его выявления может уйти довольно много времени. Все это время некоторая часть пользователей будет с недоумением смотреть на ваше приложение, впавшее в глубюокую задумчивость. Во-вторых, когда дедлок наконец будет выявлен, кто-то из юзеров получит соответствующее сообщение об ошибке, и будет пребывать в состоянии растерянности. С точки зрения его, юзверной логики, он не придпринял никаких предосудительных действий, и периодическое возникновение ошибки буквально на голом месте, да еще такой, с которой невозможно бороться никакими средствами, весьма сильно раздражает.
Обычно разработчики выбирают способ 2 (и правильно делают). Однако, этот способ в свою очередь разбивается на два диаметрально противоположных решения, каждое из которых имеет свои положительные стороны и отрицательные:
Решение 1. Заблокировать все что нужно и все что не нужно в самом начале транзакции, а потом предпринимать какие-то последовательные алгоритмические шевеления внутри транзакции уже на полностью заблокированных транзакцией ресурсах. Именно по этому пути пошли ваши разработчики. Плюсы данного решения: а) высокая степень изолированности транзакций позволяет гарантированно избежать побочных эффектов (вроде "грязного чтения"); б) простота реализации. Минусы: высокая конкуренция транзакций приводит к большим временным задержкам, потому что транзакции вынуждены ждать освобождения всех ресурсов, выстаивая в "очереди транзакций".
Решение 2. Попытаться свести к минимуму блокировки. Это решение предлагает Аджан Абдулин (и мне оно тоже больше по душе). Плюсы этого решения - возможность одновременного выполнения нескольких транзакций приводит к устранению циклов ожидания в "очереди транзакций", что положительно сказывается на быстродействии. Минусы: а) требуется тщательное продумывание всех скриптов (сложность реализации, что может приводить к ошибкам); б) возможность проявления побочных эффектов вроде "грязного чтения" на некоторых комбинациях одновременно выполняемых транзакций из-за низкого уровня изолированности транзакций.
Самый грамотный и одновременно самый трудный путь - это решение 2. Если Вам удастся уговорить ваших разработчиков по нему пойти, значит Вы родились под счастливой звездой. Базовые приемы названы Аджаном Абдулиным. По возможности во всех операциях SELECT, выполняемых по постоянным таблицам, во фразу FROM необходимо добавить хинт with (NoLock). При каждом добавлении этого хинта нужно помнить о том, что его использование может привести к "грязному чтению", и тщательно продумывать возможные влияния на другие транзакции. Во все фразы Insert, Update и Delete лучше всего поставить хинт With (RowLock). Эти операции неизбежно приводят к блокировкам, и наша задача избежать эсклации блокировок, которая может привести к дедлоку (обычно это происходит при повышении статуса блокировки до уровня страничной или табличной, что потенциально может привести к блокировке записей, расположенных по соседству с теми, над которыми выполняется операция - если другая транзакция в это время пытается получить к ним доступ, возникает опасность дедлока). Однако, следует помнить, что данный хинт можно использовать только в том случае, когда вы уверены, что эти операции всегда будут выполняться над небольшим числом записей. Если операции Insert, Update и Delete могут выполняться над большим массивом записей (сотни и тысячи), этот хинт использовать нельзя. При массовых операциях модификации записей с указанным хинтом на каждую модифицируемую запись будет занят отдельный ресурс, называемый "блокировка". Количество таких объектов при достижении критически больших величин может привести к исчерпанию ресурсов памяти SQL-сервера. Следует помнить, что даже повсеместное использование указанных хинтов не приводит гарантированно к устранению опасности возникновения дедлоков. Особое внимание следует обратить на последовательность выдачи команд UPDATE и DELETE по разным таблицам в разных скриптах. Если большая часть скриптов оперирует сразу множеством таблиц, желательно во всех скриптах придерживаться одной и той же последовательности модификации данных по нескольким таблицам.
Следует учесть, что указание табличных хинтов во фразе FROM имеет смысл только для тех таблиц, которые существуют на момент создания скрипта. Хинты по временным таблицам и таблицам Inserted и Deleted в триггерах будут проигнорированы (см. BOL).
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022889
Screem6
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за участие. Разработчики считают что просто необходимо что-то включить в SQL сервере и сразу все заработает... Но самое интересное, что все началось не так давно, и до этого нареканий не было... так что поиски продолжаются. Кстати, не в курсе, нельзя ли в SQL сервре задать единый способ обработки запросов, чтобы select всегда выполнялся как select with (nolock) и т.д.?
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022913
Oleg F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если сохранилась связь с разработчиками, можно попросить их вставить в программы команды SET LOCK_TIMEOUT
А ещё лучше не жёстко зашить timeout в программе, а вынести его во внешние настройки программы, чтобы пользователь мог сам изменять это значение без участия разработчика.
Тогда по крайней мере будет понятно, висят программы из-за того, что ожидают освобождения заблокированного ресурса, или из-за чего-то другого.
А блокировка всей таблицы в командах UPDATE - это просто хулиганство. Кто и какие проблемы надеялся это решить - непонятно. В многопользовательских базах данных это не решает проблемы, а только их порождает.
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32022919
select with(nolock) - это контролируется вызовом set transaction isolation level dirty read.
но на самом деле правильнее по умолчанию использовать read committed, и проставлять with(nolock) где нужно.
кстати, для массивных обновлений и вставок удобно правильно выставить PAGLOCK или даже TABLOCK.
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32023069
Screem6
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Господа, у меня сразу еще один вопрос, теоретический Существует ли возможность переопределения стандартыных (родных) Update, Insert и пр.?

Спасибо, за советы, сервер стал устойчивей и расторопнее
...
Рейтинг: 0 / 0
Ох уж эти блокировки
    #32023072
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Screem6:
В sql2k есть instead of триггеры. Как раз для всяческих извращений.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Ох уж эти блокировки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]