Конференция "Базы" » ненадёжность связи и TpFIBDatabase.Execute [D7, firebird]
 
  • Николай 2 (09.09.08 16:19) [0]
    Прога, соединившись с БД по инету (через GSM-модем), периодически обновляет её примерно так: pFIBDatabase.Execute('insert into ...').
    Если Execute даёт false, он повторяется с теми же параметрами после восстановления и проверки связи.
    Разрывы связи бывают часто.
    Изредка в БД получаются дубли записей, т.е. в каждом таком случае Execute даёт false, несмотря на то, что запись упешно добавлена в БД.
    Как можно решить эту проблему?
  • Sergey13 © (09.09.08 16:33) [1]
    > [0] Николай 2   (09.09.08 16:19)
    > Изредка в БД получаются дубли записей

    Значит в БД не стоит ограничение на уникальность.

    Я с ФИБ-ами не работал, но наврняка там есть работа с транзакциями. Почему надо именно так pFIBDatabase.Execute('insert into ...')? Почему нельзя просто кверик создать и делать ему execute с отловом исключения?
  • Медвежонок Пятачок © (09.09.08 16:53) [2]
    Как можно решить эту проблему?

    не инсертить по мопеду, а передавать блоб со скриптом в хранимку.
    в ней делать все инсерты.
    либо в два присеста.
    передать блоб, проверить что все ок (например сравнить crc32), затем вызвать хранимку на выполнение инсертов
  • Johnmen © (09.09.08 20:06) [3]
    1. Не слушать маньяков с хранимками.
    2. Слушать, а точнее ЧИТАТЬ, про транзакции и управление ими.
  • Медвежонок Пятачок © (09.09.08 22:07) [4]
    Изредка в БД получаются дубли записей, т.е. в каждом таком случае Execute даёт false, несмотря на то, что запись упешно добавлена в БД.
    Как можно решить эту проблему?
  • sniknik © (09.09.08 22:24) [5]
    добавить уникальное поле и проверяться по нему, если значение уже есть не добавлять... т.е. чтото типа самопальной репликации, поле репликации либо гуид, либо какой нибудь естественный ключ (если есть).
  • Sergey Masloff (09.09.08 22:32) [6]
    sniknik ©   (09.09.08 22:24) [5]
    А зачем такие сложности?
    Я хоть сам старый маньяк с хранимками но тут управления транзакциями вполне хватит.
  • Медвежонок Пятачок © (09.09.08 22:44) [7]
    хватит, особенно если нужно сделать коммит/роллбак а мопед уже потух.
  • Johnmen © (09.09.08 23:20) [8]
    когда потухает мопед, происходит как бы роллбак
  • sniknik © (09.09.08 23:25) [9]
    > А зачем такие сложности?
    вовсе не сложности, постоянно с таким работаю, обычно по естественному ключу, например составному -> подразделение-магазин-отдел-касса-z отчет-чек-номер позиции
    однозначно идентифицирует запись в общей базе хоть со всего города, и разных фирм... позволит обновлять даже задним числом. исправлять, если проблема с первоисточником (сломалась фискалка, z отчет неправильный, закрыли не видя части продаж... цто исправило, локальную базу восстановило. в глобальной что тоже искать, совмещать, и восстанавливать? нет. просто перепослать отчет и все. все что пришло частично станет полным.)
    правда в реальных базах обычно чуток посложнее, там еще заголовки по документам с суммами, что позволяет делать проверку целостности по суммам автоматом, и другая фигня.
    но это вовсе не сложно.
    не сложнее чем делать после проверку все ли дошло не имея подобного "якоря" по которому можно связать записи. ну пример с обоих концов по миллиону записей, все правильно? а может одна запись не дошла и одна задублировалась? ты говоришь у меня все правильно, а бухгалтер, "это у меня суммы не бьют", и тоже уверен что у него все правильно. и?  

    > Я хоть сам старый маньяк с хранимками
    не путай маньячество с целесообразностью... хранимка сама по себе ничего не дает. как самоцель вообще вред только от нее. а поле связи  только выгоды.
  • Медвежонок Пятачок © (10.09.08 00:35) [10]
    когда потухает мопед, происходит как бы роллбак

    Ага. А чувак уже внял советам ограничится управлением транзакциями и делал коммит когда связь прервалась.
  • Правильный$Вася (10.09.08 12:06) [11]

    > и делал коммит когда связь прервалась

    попытка коммита без связи ни к чему не приведет
  • Николай 2 (10.09.08 12:09) [12]
    Всем спасибо за ответы.

    Медвежонок Пятачок
    Короче, просто управление транзакциями не поможет?
    Каким способом лучше передать блоб?

    Johnmen
    Дык, вроде, TpFIBDatabase в этом случае сам управляет транзакцией: DefaultTransaction и DefaultUpdateTransaction заполнены - на форме есть компонент TpFIBTransaction с TimeoutAction=TARollback.
  • Медвежонок Пятачок © (10.09.08 13:50) [13]
    попытка коммита без связи ни к чему не приведет

    Это на тему ограничься управлением транзакциями.
    Мне вот интересно как он в такой среде будет это делать.
  • Медвежонок Пятачок © (10.09.08 13:52) [14]
    попытка коммита без связи ни к чему не приведет

    Ситуация:
    Связь есть.
    Посылаем коммит.
    Он (команда) долетает до сервера.
    Сервер выполнил коммит и хочет вернуть результат клиенту.
    А связи уже нет.
  • Sergey Masloff (10.09.08 14:36) [15]
    Медвежонок Пятачок ©   (10.09.08 13:52) [14]
    Это шутка или полное незнакомство с работой клиентского протокола?
    Если нетрудно назовите СУБД в которой такая ситуация возможна.
  • Медвежонок Пятачок © (10.09.08 14:38) [16]
    Какая именно ситуация?
  • Sergey Masloff (10.09.08 14:40) [17]
    Sergey Masloff   (10.09.08 14:36) [15]
    Хотя что-то подобное возможно в СУБД где commit можно на сервере делать.
    Например в Oracle - но это другая песня.
  • Sergey Masloff (10.09.08 14:41) [18]
    Медвежонок Пятачок ©   (10.09.08 14:38) [16]
    Что коммит сделается на сервере а до клиента это не дойдет? Там же с установкой соединения сессия. Пока все не отрапортуют никакого реального коммита нет. Атомарная операция
  • Медвежонок Пятачок © (10.09.08 14:43) [19]
    При чем здесь коммит на сервере/не на сервере?

    Чем с точки зрения тсп и ненадежного модема отличаются инсерт от коммита?
    Ничем.

    Клиентская либа посылает в тсп соединение данные и ждет ответа.

    И если у автора нарушается этот цикл на инсерте (запись вставлена, а exec говорит что нет), то то же самое может случиться и с коммитом.
  • Медвежонок Пятачок © (10.09.08 14:45) [20]
    Пока все не отрапортуют никакого реального коммита нет. Атомарная операция

    Ой ли?
    То есть я вызвал коммит, сервер мне ответил, все окей, убедился, что я принял его ответ, затем приступил к реальному закоммичиванию?
    А если он при этом обломается?
  • Медвежонок Пятачок © (10.09.08 14:50) [21]
    Атомарная операция

    Если бы она была атомарной, у автора не возникали бы описанные симптомы.
    Она атомарна логически, в категориях реляционной теории.

    А этажом ниже передаются биты и байты (не один байт) по неустойчивым каналам связи.
  • Sergey Masloff (10.09.08 14:51) [22]
    Медвежонок Пятачок ©   (10.09.08 14:43) [19]
    Нет. Она получает ответ и посылает чек что она его получила.  И если сервер этот чек не получил то реального коммита нет. Чтобы убедиться 100% надо смотреть исходники FB (я в этой части не смотрел) но ситуации когда коммит не прошел на клиенте а запись вставилась мне добиться не удалось при проведении стресс-тестов.
  • Медвежонок Пятачок © (10.09.08 14:53) [23]
    И как тогда объяснить случай со свершившейся вставкой на сервере и тем что exec на клиенте вернул false?
  • Sergey Masloff (10.09.08 14:54) [24]
    Медвежонок Пятачок ©   (10.09.08 14:50) [21]
    >Если бы она была атомарной, у автора не возникали бы описанные >симптомы.
    Симптомы пока только у автора ;-)
    Если бы все было так плохо они были бы у всех и постоянно.
  • Николай 2 (10.10.08 13:54) [25]
    Уникальное поле - пока не нужно.
    Заменил pFIBDatabase.Execute на pFIBQuery с ручным управлением транзакциями. Похоже, помогло.
    Не зря в одном факе настоятельно рекомендовали управлять вручную.
 
Конференция "Базы" » ненадёжность связи и TpFIBDatabase.Execute [D7, firebird]
Есть новые Нет новых   [134473   +33][b:0.001][p:0.001]