|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Нарвался на lock conflict при попытке выполнить запрос UPDATE. Начал анализировать код, но, вроде бы, нет одновременно выполняющихся транзакций. Новая стартует не раньше, чем будет выполнен COMMIT или ROLLBACK для предыдущей. Да к тому же блокировка возникает не всегда, а лишь иногда. Сумасшедшее предположение: приложение отработало слишком быстро, а сервер FB тормознул. В результате на сервер приходит команда на старт новой транзакции, когда предыдущая еще не завершилась. Имеем две различные транзакции, что делает возможным лок конфликт. Может такое быть? Если да, то есть ли культурный способ борьбы с этим безобразием, кроме как вставить что-нибудь типа Sleep(5000) перед StartTransaction? [+] Опечатка в заголовке темы: конечно же речь идет о dbExpress ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 08:29 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ, Если Commit/Rollback выполнился без ошибок - значит, транзакция на сервере завершилась 100%. Хоть я и не работал с dbExpress, но так должно быть. Еще lock может случиться, если запись удалена другой активной транзакцией, или попала в SELECT FOR UPDATE WITH LOCK. Или вообще у тебя no_rec_version и RC, там всё может быть. Но скорее всего - ты что-то у себя не заметил. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 08:49 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ, трейс всё покажет. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 11:11 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Тогда, наверное, вопросы по dbExpress 1. В приложении есть три TTransactionDesc, но TSQLConnection.InTransaction есть ли вообще активная транзакция. Можно ли узнать, какая именно транзакция стартовала? Можно ли узнать, что активны одновременно более одной транзакции? Если есть возможность как-то увязать их с TRANSACTION_ID в Firebird, то вообще замечательно. 2. Создается экземпляр TSQLQuery, в него загоняется запрос, выполняется и уничтожается. И все это без явного старта транзакции. Если имеется активная транзакция, то запрос выполнится в ней. А если активной транзакции нет, тогда как? Автоматически стартует новая транзакция? А когда она завершится? А если активных транзакций несколько, то в какой выполнится этот запрос? В транзакции с максимальным ID? автортрейс всё покажет Если можно, чуть побольше про то, что такое "трейс" и с чем его едят. Хотя бы на уровне ключевых слов и ссылок на описание. Пока все: чем я располагаю, это вставка в приложение различных запросов мониторинга, которые выполняются при возникновении конфликта (с записью результатов в лог): а потом жду: когда у кого-нибудь из пользователей снова возникнет проблемная ситуация. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 11:55 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ Тогда, наверное, вопросы по dbExpress Ясно вот что: 1. Запрос не может быть выполнен без старта транзакции, следовательно, оно умеет их стартовать автоматически, как - хз; 2. Такую ситуацию можно получить, если запущено несколько программ, работающих с одной базой. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 12:07 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ, почему такой странный выбор компонентов доступа? Приложение должно уметь работать не только с Firebird? Про трейс https://firebirdsql.org/file/documentation/release_notes/html/en/2_5/rnfb25-trace.html ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 12:17 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ автортрейс всё покажет Если можно, чуть побольше про то, что такое "трейс" и с чем его едят. Хотя бы на уровне ключевых слов и ссылок на описание.Начать можно отсюда https://firebirdsql.org/file/documentation/release_notes/html/en/2_5/rnfb25-trace.html GJ а потом жду: когда у кого-нибудь из пользователей снова возникнет проблемная ситуация. GJ Новая стартует не раньше, чем будет выполнен COMMIT или ROLLBACK для предыдущей Советую подумать над природой конфликтов обновления и понять, как они возникают. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 12:17 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Вот такой код в Delphi Код: pascal 1. 2. 3. 4.
Добавил для тестирования, что если возникает exception с текстотом "lock conflict on no wait transaction deadlock update conflicts with concurrent update concurrent transaction number is 1633032010", то выполняю вот такой запрос Код: sql 1. 2. 3. 4. 5. 6. 7.
Результаты сбрасываю в лог. Приложение мое. Да и логика приложения такова, что каждый пользователь работает со своим документом. Из личного опыта или из общих соображений может кто-нибудь подсказать, что здесь сделать, чтобы избежать конфликта либо выявить причину го возникновения? По ссылке сейчас схожу гляну. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 12:37 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
[quot GJ#22397414] как связаны между собой qTMP BConnection ? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 12:53 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
qTMP и BConnection определены в DataModule. Значение qTMP.SQLConnection равно BConnection. Задается в design-time. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:01 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ то выполняю вот такой запрос И нет гарантии, что он успеет поймать тр-цию конкурента. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:15 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
У меня он выполнялся после ROLLBACK транзакции с неудавшимся запросом UPDATE (вызов вставил в раздел EXCEPTION защищенного блога. Из сообщения об ошибке, кстати, и id транзакции-конкурента получил. Запрос выполнился, приложение и адрес в лог попали. Приложение мое. Поэтому и говорю так уверенно. Сейчас рассматриваю вариант перед выполнением запроса UPDATE проверять количество транзакций в mon$trancactions по моему аттачменту. Больше ничего в голову не приходит. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:24 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ Из личного опыта или из общих соображений может кто-нибудь подсказать, что здесь сделать, чтобы избежать конфликта либо выявить причину го возникновения? Способ избежать - не допускать такого. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:25 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
YuRock Причина - обновление записи двумя активными транзакциями. Способ избежать - не допускать такого. -- Ватсон, это был математик. -- Почему вы твак решили, Холмс?! -- Ватсон, это же элементарно! Он подумал прежде, чем ответить. Его ответ абсолютно правильный. Его ответ совершенно бесполезный. :) Про причину мне сказал сервер Firebird (только на инглише). А то, что для избегания неприятных последствий, нужно устранить причину -- очевидно. Мне же интересно, что делать дальше. Ошибка не систематическая. Возникает достаточно редко. Так что даже не знаю, как мне поможет упомянутая выше трассировка. Я же не могу сидеть на всех компьютерах заказчика месяц в ожидании, когда возникнет ошибка. По сути, у меня есть только мое приложение и его лог-файл. Соответственно, мне нужно либо сделать более безопасный код (как-то проверять наличие другой транзакции перед запуском апдейта, либо сбрасывать в лог какую-то дополнительную информацию, которая позволит мне определить, что же это за транзакция осталась болтаться, и почему она осталась болтаться. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:41 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJСейчас рассматриваю вариант перед выполнением запроса UPDATE проверять количество транзакций в mon$trancactions по моему аттачменту. Не надо пользоваться MON$ таблицами для не административных задач, иначе ваше приложение очень быстро встанет раком. Это раз. А два, для не администраторов БД MON$ таблицы видят только данные о своих соединениях ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:44 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ, Конфликты обновления в конкурентной среде - это норма. Их можно свести к минимуму грамотным проектированием и аккуратной реализацией, но полностью избавиться - вряд ли. Поэтому нужно быть к ним готовым и уметь корректно обрабатывать. И, конечно, нужно понимать их причину. PS за 9 лет так и не научились ничему ? https://www.sql.ru/forum/965872/ ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:55 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Поскольку в моем случае я вижу проблемную транзакцию, значит тут все в порядке. А чтобы приложение не встало раком, можно обращаться к таблицам мониторинга только для одного конкретного запроса UPDATE. А он выполняется не так уж и часто. И я бы рад бы, но.... Есть альтернативы? Повторяю, ошибка не систематическая, возникает редко. Анализировать код на 100 тыс. строк (который дорабатывали 10 программистов на протяжении 15 лет) в поисках возможных причин возникновения такой ситуации -- это нереально. Вот и ищу способ как выкрутиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 13:58 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJМне же интересно, что делать дальше. Ошибка не систематическая. Тебе известен запрос на котором она возникает. Тебе известна таблица, которую этот запрос обновляет. Осталось только включить мозг и понять ЗАЧЕМ он эту таблицу обновляет и ПОЧЕМУ этот запрос посылает больше одного пользователя. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 14:01 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
hvlad GJ, Конфликты обновления в конкурентной среде - это норма. Их можно свести к минимуму грамотным проектированием и аккуратной реализацией, но полностью избавиться - вряд ли. Поэтому нужно быть к ним готовым и уметь корректно обрабатывать. И, конечно, нужно понимать их причину. PS за 9 лет так и не научились ничему ? https://www.sql.ru/forum/965872/ Опять общие слова, что лучше быть богатым и здоровым, чем бедным и больным. Я и обращаюсь с просьбой, чтобы с высоты собственного опыта подсказали мне, как именно мне поступить, чтобы локализовать причину или сделать код более безопасным. А про 9 лет... По моему, можно только порадоваться, что в чужих приложениях, которые я поддерживаю, проблемы, с которыми я не могу справиться, возникают раз в 9 лет. В моих собственных приложениях у меня не возникает проблем, с которыми приходилось бы обращаться на форум. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 14:06 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJкак именно мне поступить, чтобы локализовать причину Проанализировать всю цепочку триггеров на таблице, которая изменяется запросом, выкидывающим ошибку. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 14:33 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJ Опять общие слова, что лучше быть богатым и здоровым, чем бедным и больным. GJ Я и обращаюсь с просьбой, чтобы с высоты собственного опыта подсказали мне, как именно мне поступить, чтобы локализовать причину или сделать код более безопасным. Не нравится ? Ну давай тогда стань "богатым и здоровым" ничего не делая. Нас научишь потом. GJ А про 9 лет... По моему, можно только порадоваться ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 14:56 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 15:20 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Странно. Я, вроде, описал ситуацию. Трассировка не прокатывает, потому что ошибка не систематическая и возникает редко. Аудит, скорее всего, тоже не получится: не допустит заказчик до своих серверов. Ситуацию я вам обрисовал: и как код на Delphi выглядит, и сообщение об ошибке, и как я определил, что блокирующая транзакция в моем же приложении. Представьте, что задача по поиску этой проблемы вам выдал ваш начальник. Что будете делать? Расказывать ему о том, что такое блокировки, почему они возникают, и что нужно в коде аккуратно обрабатывать конфликты? Пока был только один содержательный совет: проанализировать триггеры. Если в указанных мной условиях (возможны только модификация приложения и запись в лог-файл) нет нормального способа отыскать причину, то так и скажите, что такого способа нет, анализируй свои километры кода в поисках пропущенного завершения транзакции. Или более честный ответ "я такого способа не знаю", хоть это и бьет по самолюбию. Тогда я не буду здесь сидеть, а буду что-то изобретать... или даже анализировать километры кода. Пойду вставлять запросы к таблицам мониторинга запросы к mon$transactions и mon$statements, может там что-то нарою, что поможет выявить причину ошибки. kdv Спасибо. Все просто и понятно. Для данной проблемы мне это не поможет, но когда потребуется, буду знать, где посмотреть. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 16:55 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
GJПредставьте, что задача по поиску этой проблемы вам выдал ваш начальник. Что будете делать? Любое сообщение об ошибке в моём приложении идентифицирует её источник с точностью до вызова API. Анализировать и искать уже ничего не надо, вся необходимая информация есть в сообщении об ошибке. Осталось только пойти и понять где я облажался. Если приложение чужое, то первым и единственным вопросом будет "при каком действии возникает ошибка?" Дальше просто идёшь в код и смотришь какие запросы посылает это действие. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 17:00 |
|
Firebird + fbExpress lock conflict
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Если приложение чужое, то первым и единственным вопросом будет "при каком действии возникает ошибка?" Дальше просто идёшь в код и смотришь какие запросы посылает это действие. Ошибка возникает при попытке выполнить запрос UPDATE. Я даже знаю строку, в которой это произошло. И даже знаю причину, почему это произошло. Есть большой и ветвистый код на Delphi с большим количеством подпрограмм, который постоянно что-то вычисляет, определяет, меняет... и все это записывает в таблицу либо посредством запросов UPDATE, либо -- SELECT FROM STORED_PROC. Вроде как все эти изменения вносятся в явно стартующих транзакциях, которые сразу же (ну, или почти сразу) завершаются. Где и почему оказалась незавершенная транзакция, я понять не могу. Поэтому даже подумал было сначала, что COMMIT на сервере может выполняться асинхронно, то есть мы команду COMMIT послали и продолжили выполнение кода, а сервер из-за нагрузки тормознул и не успел сразу эту транзакцию завершить. Но мне сказали, что так не бывает. Значит где-то как-то возникло условие, при котором выполнение программы прошло по такому пути, что обошло завершение транзакции. И мне это надо найти. Вот и пытаюсь каким-то образом угадать, где именно. Хотя бы узнать, какой именно запрос изменил запись, а транзакция осталась незавершенной. Как вариант, определить перед проблемным UPDATE, что транзакция уже имеется, и не стартовать новую, а выполнить в существующей. Но тут надо аккуратно все проанализировать, чтобы не напороться на какие-нибудь другие грабли. Возможен вариант промежуточный: если на момент выполнения запроса UPDATE есть активная транзакция, сбросить в лог список всех запросов, которые в этой транзакции выполнялись. Все будет проще искать, чем рыть десятки тысяч строк плохо структурированного кода. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 17:19 |
|
|
start [/forum/topic.php?fid=40&msg=40112839&tid=1559880]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
41ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
73ms |
get tp. blocked users: |
2ms |
others: | 247ms |
total: | 410ms |
0 / 0 |