Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Firebird, InterBase Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7 8 9   вперед  Ctrl      все
 Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
Нарвался на lock conflict при попытке выполнить запрос UPDATE. Начал анализировать код, но, вроде бы, нет одновременно выполняющихся транзакций. Новая стартует не раньше, чем будет выполнен COMMIT или ROLLBACK для предыдущей. Да к тому же блокировка возникает не всегда, а лишь иногда.

Сумасшедшее предположение: приложение отработало слишком быстро, а сервер FB тормознул. В результате на сервер приходит команда на старт новой транзакции, когда предыдущая еще не завершилась. Имеем две различные транзакции, что делает возможным лок конфликт. Может такое быть? Если да, то есть ли культурный способ борьбы с этим безобразием, кроме как вставить что-нибудь типа Sleep(5000) перед StartTransaction?

[+]
Опечатка в заголовке темы: конечно же речь идет о dbExpress

Сообщение было отредактировано: 18 ноя 21, 08:33
18 ноя 21, 08:29    [22397285]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4925
GJ,

Если Commit/Rollback выполнился без ошибок - значит, транзакция на сервере завершилась 100%.
Хоть я и не работал с dbExpress, но так должно быть.

Еще lock может случиться, если запись удалена другой активной транзакцией, или попала в SELECT FOR UPDATE WITH LOCK.
Или вообще у тебя no_rec_version и RC, там всё может быть.

Но скорее всего - ты что-то у себя не заметил.
18 ноя 21, 08:49    [22397288]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
hvlad
Member

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

трейс всё покажет.
18 ноя 21, 11:11    [22397338]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
Тогда, наверное, вопросы по dbExpress

1. В приложении есть три TTransactionDesc, но TSQLConnection.InTransaction есть ли вообще активная транзакция. Можно ли узнать, какая именно транзакция стартовала? Можно ли узнать, что активны одновременно более одной транзакции? Если есть возможность как-то увязать их с TRANSACTION_ID в Firebird, то вообще замечательно.

2. Создается экземпляр TSQLQuery, в него загоняется запрос, выполняется и уничтожается. И все это без явного старта транзакции. Если имеется активная транзакция, то запрос выполнится в ней. А если активной транзакции нет, тогда как? Автоматически стартует новая транзакция? А когда она завершится? А если активных транзакций несколько, то в какой выполнится этот запрос? В транзакции с максимальным ID?

автор
трейс всё покажет

Если можно, чуть побольше про то, что такое "трейс" и с чем его едят. Хотя бы на уровне ключевых слов и ссылок на описание.
Пока все: чем я располагаю, это вставка в приложение различных запросов мониторинга, которые выполняются при возникновении конфликта (с записью результатов в лог): а потом жду: когда у кого-нибудь из пользователей снова возникнет проблемная ситуация.
18 ноя 21, 11:55    [22397378]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4925
GJ
Тогда, наверное, вопросы по dbExpress
Тут этого никто не знает.

Ясно вот что:
1. Запрос не может быть выполнен без старта транзакции, следовательно, оно умеет их стартовать автоматически, как - хз;
2. Такую ситуацию можно получить, если запущено несколько программ, работающих с одной базой.
18 ноя 21, 12:07    [22397389]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
Симонов Денис
Member

Откуда: Рязань
Сообщений: 11092
GJ,

почему такой странный выбор компонентов доступа? Приложение должно уметь работать не только с Firebird?

Про трейс https://firebirdsql.org/file/documentation/release_notes/html/en/2_5/rnfb25-trace.html
18 ноя 21, 12:17    [22397397]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
hvlad
Member

Откуда:
Сообщений: 11551
GJ
автор
трейс всё покажет

Если можно, чуть побольше про то, что такое "трейс" и с чем его едят. Хотя бы на уровне ключевых слов и ссылок на описание.
Начать можно отсюда
https://firebirdsql.org/file/documentation/release_notes/html/en/2_5/rnfb25-trace.html

GJ
а потом жду: когда у кого-нибудь из пользователей снова возникнет проблемная ситуация.
Т.е. пользователей более одного. Тогда вот это вот
GJ
Новая стартует не раньше, чем будет выполнен COMMIT или ROLLBACK для предыдущей
вообще ни о чём.

Советую подумать над природой конфликтов обновления и понять, как они возникают.
18 ноя 21, 12:17    [22397398]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
Вот такой код в Delphi
  qTMP.SQL.Text := SQLText; // текст UPDATE запроса
  BConnection.StartTransaction(Trans);
  qTMP.ExecSQL;
  BConnection.Commit(Trans);


Добавил для тестирования, что если возникает exception с текстотом "lock conflict on no wait transaction deadlock update conflicts with concurrent update concurrent transaction number is 1633032010", то выполняю вот такой запрос
SELECT
  a.mon$attachment_id, a.mon$remote_address, a.mon$remote_process
FROM
  mon$transactions t
  INNER JOIN mon$attachments a ON a.mon$attachment_id = t.mon$attachment_id
WHERE
  t.mon$transaction_id = 1633032010


Результаты сбрасываю в лог. Приложение мое. Да и логика приложения такова, что каждый пользователь работает со своим документом.

Из личного опыта или из общих соображений может кто-нибудь подсказать, что здесь сделать, чтобы избежать конфликта либо выявить причину го возникновения?

По ссылке сейчас схожу гляну.
18 ноя 21, 12:37    [22397414]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
pastor
Member

Откуда: Калуга
Сообщений: 1313
[quot GJ#22397414]

как связаны между собой

qTMP
BConnection

?
18 ноя 21, 12:53    [22397425]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
qTMP и BConnection определены в DataModule. Значение qTMP.SQLConnection равно BConnection. Задается в design-time.
18 ноя 21, 13:01    [22397434]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
hvlad
Member

Откуда:
Сообщений: 11551
GJ
то выполняю вот такой запрос
Его нужно выполнять в отдельной тр-ции.
И нет гарантии, что он успеет поймать тр-цию конкурента.
18 ноя 21, 13:15    [22397450]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
У меня он выполнялся после ROLLBACK транзакции с неудавшимся запросом UPDATE (вызов вставил в раздел EXCEPTION защищенного блога. Из сообщения об ошибке, кстати, и id транзакции-конкурента получил. Запрос выполнился, приложение и адрес в лог попали. Приложение мое. Поэтому и говорю так уверенно.

Сейчас рассматриваю вариант перед выполнением запроса UPDATE проверять количество транзакций в mon$trancactions по моему аттачменту. Больше ничего в голову не приходит.
18 ноя 21, 13:24    [22397457]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 4925
GJ
Из личного опыта или из общих соображений может кто-нибудь подсказать, что здесь сделать, чтобы избежать конфликта либо выявить причину го возникновения?
Причина - обновление записи двумя активными транзакциями.
Способ избежать - не допускать такого.
18 ноя 21, 13:25    [22397459]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
YuRock
Причина - обновление записи двумя активными транзакциями.
Способ избежать - не допускать такого.

-- Ватсон, это был математик.
-- Почему вы твак решили, Холмс?!
-- Ватсон, это же элементарно! Он подумал прежде, чем ответить. Его ответ абсолютно правильный. Его ответ совершенно бесполезный.
:)

Про причину мне сказал сервер Firebird (только на инглише). А то, что для избегания неприятных последствий, нужно устранить причину -- очевидно.

Мне же интересно, что делать дальше. Ошибка не систематическая. Возникает достаточно редко. Так что даже не знаю, как мне поможет упомянутая выше трассировка. Я же не могу сидеть на всех компьютерах заказчика месяц в ожидании, когда возникнет ошибка. По сути, у меня есть только мое приложение и его лог-файл. Соответственно, мне нужно либо сделать более безопасный код (как-то проверять наличие другой транзакции перед запуском апдейта, либо сбрасывать в лог какую-то дополнительную информацию, которая позволит мне определить, что же это за транзакция осталась болтаться, и почему она осталась болтаться.
18 ноя 21, 13:41    [22397469]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
Симонов Денис
Member

Откуда: Рязань
Сообщений: 11092
GJ
Сейчас рассматриваю вариант перед выполнением запроса UPDATE проверять количество транзакций в mon$trancactions по моему аттачменту.


Не надо пользоваться MON$ таблицами для не административных задач, иначе ваше приложение очень быстро встанет раком. Это раз.
А два, для не администраторов БД MON$ таблицы видят только данные о своих соединениях
18 ноя 21, 13:44    [22397471]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
hvlad
Member

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


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

PS за 9 лет так и не научились ничему ?
https://www.sql.ru/forum/965872/
18 ноя 21, 13:55    [22397481]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
Поскольку в моем случае я вижу проблемную транзакцию, значит тут все в порядке.
А чтобы приложение не встало раком, можно обращаться к таблицам мониторинга только для одного конкретного запроса UPDATE. А он выполняется не так уж и часто.

И я бы рад бы, но.... Есть альтернативы? Повторяю, ошибка не систематическая, возникает редко. Анализировать код на 100 тыс. строк (который дорабатывали 10 программистов на протяжении 15 лет) в поисках возможных причин возникновения такой ситуации -- это нереально. Вот и ищу способ как выкрутиться.
18 ноя 21, 13:58    [22397487]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
Dimitry Sibiryakov
Member

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

GJ
Мне же интересно, что делать дальше. Ошибка не систематическая.

Тебе известен запрос на котором она возникает. Тебе известна таблица, которую
этот запрос обновляет. Осталось только включить мозг и понять ЗАЧЕМ он эту
таблицу обновляет и ПОЧЕМУ этот запрос посылает больше одного пользователя.

Posted via ActualForum NNTP Server 1.5

18 ноя 21, 14:01    [22397488]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
hvlad
GJ,
Конфликты обновления в конкурентной среде - это норма. Их можно свести к минимуму грамотным проектированием и аккуратной реализацией,
но полностью избавиться - вряд ли. Поэтому нужно быть к ним готовым и уметь корректно обрабатывать.
И, конечно, нужно понимать их причину.

PS за 9 лет так и не научились ничему ?
https://www.sql.ru/forum/965872/

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

А про 9 лет... По моему, можно только порадоваться, что в чужих приложениях, которые я поддерживаю, проблемы, с которыми я не могу справиться, возникают раз в 9 лет. В моих собственных приложениях у меня не возникает проблем, с которыми приходилось бы обращаться на форум.
18 ноя 21, 14:06    [22397491]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
Dimitry Sibiryakov
Member

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

GJ
как именно мне поступить, чтобы локализовать причину

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

Posted via ActualForum NNTP Server 1.5

18 ноя 21, 14:33    [22397515]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
hvlad
Member

Откуда:
Сообщений: 11551
GJ
Опять общие слова, что лучше быть богатым и здоровым, чем бедным и больным.
Имеющий уши - услышит. Ты хочешь, чтобы тебе пальцем место в коде показали ? Легко - ошибка в 17-ой строке (ц)

GJ
Я и обращаюсь с просьбой, чтобы с высоты собственного опыта подсказали мне, как именно мне поступить, чтобы локализовать причину или сделать код более безопасным.
Уже сказали - трейс (аудит) чтобы найти причину, плюс обработка конфликтов в коде.
Не нравится ? Ну давай тогда стань "богатым и здоровым" ничего не делая. Нас научишь потом.

GJ
А про 9 лет... По моему, можно только порадоваться
Не возражаю - можно и порадоваться. Вот только эти самые грабли уже обсуждали 9 лет назад и рецепт был тот же. Удивительно ?
18 ноя 21, 14:56    [22397526]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
kdv
Member

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

дарю:
http://www.ibase.ru/how_to_track_deadlocks/
18 ноя 21, 15:20    [22397541]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

Откуда:
Сообщений: 50
Странно. Я, вроде, описал ситуацию. Трассировка не прокатывает, потому что ошибка не систематическая и возникает редко. Аудит, скорее всего, тоже не получится: не допустит заказчик до своих серверов. Ситуацию я вам обрисовал: и как код на Delphi выглядит, и сообщение об ошибке, и как я определил, что блокирующая транзакция в моем же приложении. Представьте, что задача по поиску этой проблемы вам выдал ваш начальник. Что будете делать? Расказывать ему о том, что такое блокировки, почему они возникают, и что нужно в коде аккуратно обрабатывать конфликты? Пока был только один содержательный совет: проанализировать триггеры.

Если в указанных мной условиях (возможны только модификация приложения и запись в лог-файл) нет нормального способа отыскать причину, то так и скажите, что такого способа нет, анализируй свои километры кода в поисках пропущенного завершения транзакции. Или более честный ответ "я такого способа не знаю", хоть это и бьет по самолюбию. Тогда я не буду здесь сидеть, а буду что-то изобретать... или даже анализировать километры кода. Пойду вставлять запросы к таблицам мониторинга запросы к mon$transactions и mon$statements, может там что-то нарою, что поможет выявить причину ошибки.

kdv
GJ,

дарю:
http://www.ibase.ru/how_to_track_deadlocks/

Спасибо. Все просто и понятно. Для данной проблемы мне это не поможет, но когда потребуется, буду знать, где посмотреть.
18 ноя 21, 16:55    [22397603]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
Dimitry Sibiryakov
Member

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

GJ
Представьте, что задача по поиску этой проблемы вам выдал ваш начальник. Что
будете делать?

Любое сообщение об ошибке в моём приложении идентифицирует её источник с
точностью до вызова API. Анализировать и искать уже ничего не надо, вся
необходимая информация есть в сообщении об ошибке. Осталось только пойти и
понять где я облажался.

Если приложение чужое, то первым и единственным вопросом будет "при каком
действии возникает ошибка?" Дальше просто идёшь в код и смотришь какие запросы
посылает это действие.

Posted via ActualForum NNTP Server 1.5

18 ноя 21, 17:00    [22397608]     Ответить | Цитировать Сообщить модератору
 Re: Firebird + fbExpress lock conflict  [new]
GJ
Member

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

Если приложение чужое, то первым и единственным вопросом будет "при каком
действии возникает ошибка?" Дальше просто идёшь в код и смотришь какие запросы
посылает это действие.

Ошибка возникает при попытке выполнить запрос UPDATE. Я даже знаю строку, в которой это произошло. И даже знаю причину, почему это произошло. Есть большой и ветвистый код на Delphi с большим количеством подпрограмм, который постоянно что-то вычисляет, определяет, меняет... и все это записывает в таблицу либо посредством запросов UPDATE, либо -- SELECT FROM STORED_PROC. Вроде как все эти изменения вносятся в явно стартующих транзакциях, которые сразу же (ну, или почти сразу) завершаются. Где и почему оказалась незавершенная транзакция, я понять не могу. Поэтому даже подумал было сначала, что COMMIT на сервере может выполняться асинхронно, то есть мы команду COMMIT послали и продолжили выполнение кода, а сервер из-за нагрузки тормознул и не успел сразу эту транзакцию завершить. Но мне сказали, что так не бывает. Значит где-то как-то возникло условие, при котором выполнение программы прошло по такому пути, что обошло завершение транзакции. И мне это надо найти. Вот и пытаюсь каким-то образом угадать, где именно. Хотя бы узнать, какой именно запрос изменил запись, а транзакция осталась незавершенной. Как вариант, определить перед проблемным UPDATE, что транзакция уже имеется, и не стартовать новую, а выполнить в существующей. Но тут надо аккуратно все проанализировать, чтобы не напороться на какие-нибудь другие грабли.

Возможен вариант промежуточный: если на момент выполнения запроса UPDATE есть активная транзакция, сбросить в лог список всех запросов, которые в этой транзакции выполнялись. Все будет проще искать, чем рыть десятки тысяч строк плохо структурированного кода.
18 ноя 21, 17:19    [22397619]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7 8 9   вперед  Ctrl      все
Все форумы / Firebird, InterBase Ответить