UniDAC EIBCError with message 'cannot disconnect database with open transactions'

X11
Дата: 08.07.2019 14:20:31
При закрытии приложения появилась ошибка:
Project raised exception class EIBCError with message 'cannot disconnect database with open transactions (1 active)'.

Раньше такого не было.
В приложении несколько UniConnection и, соответственно, несколько наборов данных со своими транзакциями.

В ошибке, как видите, нет ссылки на компоненту, откуда лезет исключение :(
здесь рекомендуют:
https://forums.devart.com/viewtopic.php?t=35596#p123776
Check the TUniConnection.DefaultTransaction.DefaultCloseAction, its default is taRollback.
Also TUniConnection.Autocommit, default for FB is True.

так и сделано.


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


Delphi Tokyo
UniDAC 7.1.4
Firebird 3.
X11
Дата: 08.07.2019 14:38:15
А ларчик просто открывался.
Забыл при закрытии приложения вызвать деструктор класса, где выполнялся Disconnect.
Запутася. Сам виноват.
X11
Дата: 08.07.2019 14:40:52
Но странно, что раньше этой ошибки не возникало.
X11
Дата: 08.07.2019 14:55:25
Всё равно ошибка то появляется, то исчезает.
Такое впечатление, что библиотека сама не закрывает транзакции при разрыве связи.
Возможно, что приложение где-то в процессе работы стартует транзации, но не завершает их, что вполне нормально вроде бы.
X11
Дата: 08.07.2019 15:12:23
destructor TObjectsSearch.Destroy;
begin
// connNotify TUniConnection

  if Assigned(connNotify) then
  begin
    ShowMessage(connNotify.TransactionCount.ToString);

    if connNotify.Connected then
      connNotify.Disconnect;

    ShowMessage(connNotify.TransactionCount.ToString);

    if connNotify.InTransaction then
      ShowMessage('InTransaction');// это сообщение не появляется

    connNotify.DisposeOf;
  end;


ShowMessage показывает 2 раза значение "3", а это нормально?
И в доках свойство TransactionCount не описано
https://www.devart.com/unidac/docs/devart.unidac.tuniconnection members.htm
kill_zdm
Дата: 08.07.2019 15:23:06
Позвольте мое скромное мнение
https://www.devart.com/unidac/docs/devart.unidac.tuniconnection.starttransaction().htm
Мне кажется проблема в уровне изоляции запуска транзакции в случае нештатных последствий соединения , а точнее - на поведение -ждать или откатить или подтвердить. Я бы попробовал, ради интереса, поиграться с параметрами запуска транзакций.
X11
Дата: 08.07.2019 15:43:15
Игрался и доигрался Картинка с другого сайта.

Потом всё вернул всад. Но проблема иногда проявляется. Вот и не могу найти закономерность.


Вообще, хочу сделать, как на фибах: одна транзакция читающая и постоянно открытая, а вторая - пишущая и максимально короткая, т.е. только на время записи.

procedure TObjectsSearch.InitDB;
begin
  connNotify := TUniConnection.Create(nil);
  InterBaseUniProvider1    := TInterBaseUniProvider.Create(connNotify);
  connNotify.ProviderName  := 'InterBase';
  connNotify.ConnectString := fConnectionString;
  connNotify.AutoCommit    := True;

  transW := TUniTransaction.Create(nil);
  transW.IsolationLevel     := ilCustom;
  transW.DefaultCloseAction := taRollback;
  transW.DefaultConnection  := connNotify;
  transW.SpecificOptions.Values['Params'] := 'write;nowait;rec_version;read_committed';

  transR := TUniTransaction.Create(nil);
  transR.IsolationLevel     := ilCustom;
  transR.DefaultCloseAction := taRollback;
  transR.DefaultConnection  := connNotify;
  transR.SpecificOptions.Values['Params'] := 'read;nowait;rec_version;read_committed';

  connNotify.DefaultTransaction := transR;

  connNotify.Connect;

  qQueryValue := TUniQuery.Create(connNotify);
  qQueryValue.Connection := connNotify;
  qQueryValue.Transaction := transR;
  qQueryValue.UpdateTransaction := transW;


может я неправильно создаю и уничтожаю элементы?

destructor TObjectsSearch.Destroy;
begin
  if Assigned(connNotify) then
  begin
    if connNotify.Connected then
      connNotify.Disconnect;
    connNotify.DisposeOf;
  end;

  if Assigned(transW) then
    transW.DisposeOf;

  if Assigned(transR) then
    transR.DisposeOf;


Не в том порядке?
Может нужно принудительно закрывать транзакции? Хотя у компоненты есть же свойство DefaultCloseAction:
https://www.devart.com/unidac/docs/devart.dac.tdatransaction.defaultcloseaction.htm
Use DefaultCloseAction to specify the transaction behaviour when it is destroyed while being active, or when one of its connections is closed with the active transaction.
_Vasilisk_
Дата: 08.07.2019 16:05:53
X11
Но проблема иногда проявляется. Вот и не могу найти закономерность.
Многопоток?
X11
Дата: 08.07.2019 16:07:58
Ну почти.
Есть основное приложение с двумя соединениями и отдельный поток с ещё одним.
X11
Дата: 08.07.2019 16:10:06
Но я уверен на 99%, что исключение появляется не в отдельном потоке.
Ну т.е. я как бы понял уже из-за какого соединения ошибка, осталдось понять причины и закономерность и как правильно завершать приложение, если UniDAC сама не умеет правильно управлять транзакциями при завершении приложения.