fibplus icon indicating copy to clipboard operation
fibplus copied to clipboard

TpFIBQuery. закрытие транзакции после первого фетча

Open dshumko opened this issue 8 years ago • 8 comments

если у TpFIBQuery задать следующие параметры GoToFirstRecordOnExecute = True; qoStartTransaction = true qoAutoCommit = true то при выборке select происходит закрытие транзакции после первого фетча, что приводит к ошибке выполнения

смотрим код в версия 7.6 код

if FGoToFirstRecordOnExecute
then begin
    DoAfterExecute(Assigned(FMDTMainDataOrder), vAfterExecEvent);
    vAfterExecEvent := False;
    Next;
end;

в версии 7.5 код был такой

if FGoToFirstRecordOnExecute then
    Next;

думаю DoAfterExecute лишний в версии 7.6 этот код выполнится позже

dshumko avatar Nov 10 '16 11:11 dshumko

Да, там проблема, при select стэйтментов он все равно делает commit в DoAfterExecute. Позже этот код не выполняется так как ставится флаг vAfterExecEvent. Буду переделывать как у датасетов: Если select то не сделать Commit. Наверное это лучший компроммис когда AutoCommit.

madorin avatar Nov 10 '16 12:11 madorin

я правильно понимаю, что тут может помочь пока только использование FetchAll ?

vkrapotkin avatar Nov 10 '16 13:11 vkrapotkin

FetchAll нет в FIBQuery. для себя закомментировал

if FGoToFirstRecordOnExecute
then begin
    // DoAfterExecute(Assigned(FMDTMainDataOrder), vAfterExecEvent);
    // vAfterExecEvent := False;
    Next;
end;

dshumko avatar Nov 10 '16 14:11 dshumko

точно. посмотрел. это в Dataset реализовано как Bookmark + Last

vkrapotkin avatar Nov 10 '16 14:11 vkrapotkin

Данный фикс "сломал" функционал получения количества записей, который был раньше работал корректно и вполне логично: В событии OnAfterExecute проверяется количество записей через свойство RecordCount. Соответственно перенос кода

if FGoToFirstRecordOnExecute and FOpen then
    Next;

после вызова события DoAfterExecute не логично и "ломает" работу компонента.

  1. При проверке количества записей в событии DoAfterExecute соответственно получаем 0.
  2. Выбор следующей записи вполне логично для SQLSelect, а не для всех типов SQL.
  3. DoAfterExecute как следует из названия должен выполнялся самой последней инструкцией, после всех действий.

Лучше явно управлять транзакциями, чем пытаясь вылечить "автоматический" режим "сломать" основной функционал.

AnryJester avatar Dec 12 '16 11:12 AnryJester

Привет, AnryJester, Да, щас проблема в том что DoAfterExecute вызывается до Next и собственно получается RecordCount = 0. Хотя незнаю если правильнее так как было. Будем править, чтобы не ломать совместимость.

madorin avatar Dec 12 '16 13:12 madorin

Anry, смотрел код.

В 7.6 DoAfterExecute и выполняется до Next, независимо от этого фикса. этого было до. В 7.5 было иначе да, сначала Next а потом DoAfterExecute. Я нахожу логику в 7.6 более правильной. В DoAfterExecute RecordCound максимум может быть 1, после одного фетча что позволяет проверять только если есть записи и ничего другое. Посмотрим что скажет сообщество. Можно фиксить только ради совместимости.

  1. Выбор следующей записи вполне логично для SQLSelect, а не для всех типов SQL.

Еще для сингулярных запросов тоже, типа execute procedure. Хотя в FB3 уже это не работает. Уже курсор с одной записи не открывается.

  1. DoAfterExecute как следует из названия должен выполнялся самой последней инструкцией, после всех действий.

Next уже как бы не связан с Execute. есть isc_execute а есть isc_fetch.

madorin avatar Dec 12 '16 14:12 madorin

Я бы вообще описал RecordCount как deprecated По идее, нужно бы пользоваться явным RecordCountFromSrv

vkrapotkin avatar Dec 12 '16 17:12 vkrapotkin