Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Firebird, InterBase Новый топик    Ответить
 Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Знатоки, будьте добры, подскажите по матчасти. Имеются два клиентских приложения на Delphi (на фибплюсах), которые одновременно могут делать insert/update/delete в одни и те таблицы. С недавних пор начал возникать lock conflict on no wait transaction (concurrent update).

Итак, вопросы:

1. Обязательна ли транзакция при update в таблицу (trModifyDoc - FibTransaction)?

 
if not trModifyDoc.InTransaction then
   trModifyDoc.StartTransaction;
...
   QueryDataMatrix.Close;
   QueryDataMatrix.SQL.Clear;
   QueryDataMatrix.SQL.Add('Update DataMatrixes...
   QueryDataMatrix.ExecQuery;
...
if trModifyDoc.InTransaction then
   trModifyDoc.Commit;


Довольно давно уже в одном приложении убрал вообще транзакцию
if not trModifyDoc.InTransaction then
   trModifyDoc.StartTransaction;


Теперь вот думаю - не последствия ли этого проявляются deadlock-ом

2. Если транзакия необязательна, то простой update без транзакции вида
QueryDataMatrix.SQL.Add('Update DataMatrixes...

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

3. Как влияют друг на друга вложенные транзакции, висящии на разных компонентах FibTransaction
Скажем

..
if not trWriteDoc.InTransaction then
   trModifyDoc.StartTransaction;
...
if not trModifyDoc.InTransaction then
   trModifyDoc.StartTransaction;
...
if trModifyDoc.InTransaction then
   trModifyDoc.Commit;
...
if not trWriteDoc2.InTransaction then
   trModifyDoc2.StartTransaction;
...
if not trModifyDoc2.InTransaction then
   trModifyDoc2.StartTransaction;
...
if trModifyDoc2.InTransaction then
   trModifyDoc2.Commit;
...
if trWrite.InTransaction then
   trWrite.Commit;


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

Не лучше ли сделать одну общую транзакцию для одного приложения и также одну общую на все апдейты для второго?
Или же этого ничего не даст в плане борьбы с deadlock-ами?

Сообщение было отредактировано: 9 окт 21, 00:32
9 окт 21, 00:43    [22381487]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Да еще такой вопрос - как лучше - для каждого FibQuery создавать отдельную FibTransaction
или все Query скажем на апдейт вешать на один FibTransaction
То есть Query1 -> trModifyDoc1, Query2 -> trModifyDoc2, Query3 -> trModifyDoc3
или же
Query1 -> trModifyDoc1, Query2 -> trModifyDoc1, Query3 -> trModifyDoc1

К сообщению приложен файл. Размер - 28Kb
9 окт 21, 00:57    [22381493]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54772
В Firebird ничто не может выполняться вне транзакции. Точка. (Пара исключений -
за пределами твоих потребностей.)

В Firebird нет вложенных транзакций, только параллельные.

Старт и финиш транзакций диктуется в основном бизнес-логикой.

Сообщение было отредактировано: 9 окт 21, 00:48
9 окт 21, 00:57    [22381494]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
ъъъъъ
Member

Откуда:
Сообщений: 2653
арт2010,

1. Стартуй и завершай транзакции для каждой атомарной бизнес - операции.
2. Вложенных транзакций не бывает.
2. Для каждого FibQuery создавать отдельную FibTransaction не нужно.
9 окт 21, 01:04    [22381497]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Благодарю за помощь! И наконец еще такой вопрос - имеет смысл логику транзакций перевесить с клиента на триггеры в самой БД? Ну то есть к примеру убираю запрос
 update вспомогательная таблица 
и вместо него вешаю триггер на AfterInsert в основной таблице - это поможет избежать deadlock-ов или вообще без разницы?

Сообщение было отредактировано: 9 окт 21, 01:00
9 окт 21, 01:07    [22381499]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
ъъъъъ
Member

Откуда:
Сообщений: 2653
арт2010,

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

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

Вот тут подробности, если интересно: http://www.ibase.ru/ibtrans/
9 окт 21, 01:17    [22381500]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54772

арт2010
это поможет избежать deadlock-ов или вообще без разницы?

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

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

Posted via ActualForum NNTP Server 1.5

9 окт 21, 12:30    [22381569]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Ivan_Pisarevsky
Member

Откуда: НН
Сообщений: 8877
арт2010
Благодарю за помощь! И наконец еще такой вопрос - имеет смысл логику транзакций перевесить с клиента на триггеры в самой БД? Ну то есть к примеру убираю запрос
 update вспомогательная таблица 

и вместо него вешаю триггер на AfterInsert в основной таблице - это поможет избежать deadlock-ов или вообще без разницы?
Без понимания сути процесса сложно сказать определенно.

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

Далее дэдлок это не "ПРОБЛЕМА" от которой надо непременно избавиться, это может быть просто часть бизнес процесса и ее надо корректно обработать. смотреть по задаче, которая не озвучена.

Как пример: может быть широкая таблица заголовка первичного документа и в ней поле "статус" апдейт которого потенциальный дэдлок, если поле "статус" вынести в пристыкованную табличку и делать туда только инсерты с типом статуса и штампом времени, а в документ тащить ровно последний по штампу времени, то дедлок на смене статуса документа не придет в принципе.
9 окт 21, 12:45    [22381575]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Насчет логики - не буду спорить, почти все было сделано до меня, сейчас приходится надстраивать относительно текущих реалий
Есть две таблицы journaldoc - таблица приходных и расходных доков (чеков, итд) и tabledoc - строк этих доков. На уровне БД целостность не контролируется. Приходники соответственно со знаком +, расходники -
При этом возможная проблема была изначально в том, что в tabledoc строки сворачиваются. То есть грубо говоря пришло 4 упаковки одинакового товара (id_tovara, id_proizv, id_serii, cena) - они будут все идти одной строкой, где kolvo = 4
И продажи раньше также шли одной строкой до внедрения онлайн касс и требования слать в ОФД каждую позицию. С тех пор позиции чека пишутся в tabledoc построчно.

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

Как я понимаю сейчас происходит дэдлок именно на datamatrixes (жалко что FB не показывает имя таблицы в ошибке).
Так как сейчас при пробитии чека идет update datamatrixes в кассовой проге и одновременно может быть insert into datamatrixes в складской проге. Но опять таки очень странно как так получается, потому что один и тот же набор данных никак не должен обрабатываться, так как сам datamatrix - это уникальный ключ, которые на может повторяться - даже на уровне сканирования сделал удаление дублей, если случайно 2 раза одно и то же отсканируют. То есть по идее не может быть вообще одновременного обращения к одной и той же записи таблицы datamatrixes, но deadlock тем не менее есть

Кстати кроме дэдлока еще возникла неприятная проблема - на некоторых точках (не везде) начались взаимные подвешивания обоих прог (касовой и складской). в момент активного приема товара в складской - но уже без дэдлока. Тут не могу понять в чем. Может concurrent update вызывать такое подвисание - 5, 10 , 20 минут? Либо же проблема в том, что при выводе некоторых форм используется циклы while not true и всякие события, логика которых возможно нарушилась с внесением изменений по маркировке

Сообщение было отредактировано: 9 окт 21, 12:55
9 окт 21, 13:01    [22381580]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54772
арт2010
Как я понимаю сейчас происходит дэдлок именно на datamatrixes (жалко что FB не
показывает имя таблицы в ошибке).

В запросе update может указываться только одна таблица. Перепутать невозможно.

Или ты даже не в состоянии отследить какой именно запрос возвращает ошибку? Тогда аудит и трассировка тебе в руки.

арт2010
Кстати кроме дэдлока еще возникла неприятная проблема - на некоторых точках (не везде) начались взаимные подвешивания обоих прог (касовой и складской). в момент активного приема товара в складской - но уже без дэдлока.

А вот это уже может быть как раз дедлок. Научись-таки его отличать от конфликта обновления.

Сообщение было отредактировано: 9 окт 21, 12:57
9 окт 21, 13:06    [22381582]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Ivan_Pisarevsky
Member

Откуда: НН
Сообщений: 8877
Так как сейчас при пробитии чека идет update datamatrixes в кассовой проге

Выкинуть апдейт нахрен.
9 окт 21, 13:12    [22381583]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Ivan_Pisarevsky
Member

Откуда: НН
Сообщений: 8877
ХШ не подвел, как именно выкинуть я уже выше написал.
9 окт 21, 13:13    [22381584]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
kdv
Member

Откуда: iBase.ru
Сообщений: 30244
арт2010,

классическая проблема, когда писали "однопользовательское" приложение, а потом вдруг оно оказалось многопользовательским.
Про то, сколько транзакций и куда, написано в
https://www.ibase.ru/ibx
ближе к концу в разделе
"Использование и управление IBTransaction в приложениях"
не смотря на то, что статья про IBX, она абсолютно точно относится и к FIBPlus.
9 окт 21, 15:29    [22381623]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
ggreggory
Member

Откуда:
Сообщений: 182
Dimitry Sibiryakov

В Firebird нет вложенных транзакций, только параллельные.


ъъъъъ

2. Вложенных транзакций не бывает.


Возражу. Вложенные транзакции в Firebird есть и поддерживаются FibPlus с помощью этих методов:

TFIBTransaction.SetSavePoint
TFIBTransaction.RollBackToSavePoint
TFIBTransaction.ReleaseSavePoint

Вот статейка по теме:

https://www.ibase.ru/savepoints/
9 окт 21, 17:12    [22381656]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Старый плюшевый мишка
Member

Откуда:
Сообщений: 1128
Dimitry Sibiryakov

В запросе update может указываться только одна таблица. Перепутать невозможно.


Триггера ;)
9 окт 21, 19:15    [22381729]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Господа, в продолжении темы. Решил идти по пути - убрать все апдейты, а необходимые делиты из таблицы текущих остатков датаматриксов делать раз в сутки по событию. Сейчас споткнулся о вот такой запрос - выполняется 15 ms - что недопустимо много, учитывая что в CurDataM всего 5 тысяч записей. Подскажите как оптимизировать? Сразу выбирать не получится, так как сначала надо определить sgtin-ы и потом уже по каждому минимальное кол-во. Значения сразу подставил, но в реале они подставляютя праметрами в цикле по строкам документа. А строк может и 100. Так что по 15 ms на 2 записи - что-то дохрена
Select SGTIN, min(ostatok) as ostatok from CurDataM where SGTIN in
         (Select SGTIN From CurDataM where
         (idtabledoc = 243963)
         and (idtovar = 12854) and (idproizv = 86)
         and (idserii = 246127))
         group by SGTIN;

План запроса на скрине

Сообщение было отредактировано: 17 окт 21, 13:04
17 окт 21, 13:12    [22384718]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475


К сообщению приложен файл. Размер - 15Kb
17 окт 21, 13:13    [22384719]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54772

Убери IN, он тут напрочь не нужен.

Posted via ActualForum NNTP Server 1.5

17 окт 21, 13:15    [22384722]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
Dimitry Sibiryakov, так просто не убрать. В подзапросе нет нужных записей. Поэтому приходится подзапросом определять нужные sgtin-ы и потом уже новым select-ом по всей таблице искать нужные записи по sgtin с мин. кол-вом. Можно конечно попробовать join-ом, но не уверен будет ли быстрее. Интересно есть еще какие-нибудь конструкции чтобы максимально ускорить join таблицы с самой собой

Сообщение было отредактировано: 17 окт 21, 13:13
17 окт 21, 13:24    [22384724]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 54772

арт2010
Можно конечно попробовать join-ом, но не уверен будет ли быстрее.

Будет.

И пересмотри свои требования к таймингу, 15мс это минимально засекаемое время на
Windows обычными методами.

Posted via ActualForum NNTP Server 1.5

17 окт 21, 13:40    [22384731]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
hvlad
Member

Откуда:
Сообщений: 11551
арт2010
Картинка с другого сайта.
В таблице нет индексов ?
17 окт 21, 14:01    [22384733]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
ggreggory
Member

Откуда:
Сообщений: 182
арт2010
15 ms - что недопустимо много


Поместите запрос в Execute Block и выполните его в цикле 1000 раз. Тогда делением получите реальный тайминг. Вполне возможно, что вы не там ищете проблему.
17 окт 21, 19:37    [22384814]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
арт2010
Member

Откуда:
Сообщений: 475
hvlad, так точно, создал, взлетело
17 окт 21, 20:37    [22384832]     Ответить | Цитировать Сообщить модератору
 Re: Борьба с deadlock - lock conflict on no wait transaction (concurrent update)  [new]
hvlad
Member

Откуда:
Сообщений: 11551
арт2010,

если я правильно понял задачу, то нужно что-то вроде

select c.SGTIN, (select min(c2.ostatok) from CurDataM c2 where c2.SGTIN = c.SGTIN)
  from CurDataM c join tabledoc d   -- tabledoc - строки документа и таблица(ы) с хар-ками товара
    on c.idtabledoc = d.idtabledoc 
   and c.idtovar = d.idtovar 
   and c.idproizv = d.idproizv 
   and c.idserii = d.idserii 
 where d.docid = :docid -- нужный документ
group by c.SGTIN


Сообщение было отредактировано: 17 окт 21, 22:23
17 окт 21, 22:33    [22384846]     Ответить | Цитировать Сообщить модератору
Все форумы / Firebird, InterBase Ответить