Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
Добрый день. Решил написать небольшое приложение под Linux. Для выполнения запросов взял FireDAC. Запрос выполняется, все хорошо, пока с сетью проблем нет. Через раз при выполнении запроса вылетает ошибка, что соединение потеряно, следовательно нужно переподключаться. Делаю так

try
    FDQuery.ExecSQL; //если не вовремя, то возвращается ошибка
    FDQuery.Close;
except
   on E: EFDDBEngineException do begin
    if E.Kind = ekServerGone then
    EConnect:= True
    else  EOracle:= True;
    end;
    on E: EFDException do begin
     EFD:= True;
     end;
     on E: exception do begin
     EOther:= True;
     end;
end;


Если ошибка связи, то EConnect:= True

Далее, в цикле пытаюсь соединиться

function CheckConnection: boolean;
var
  Q: TFDQuery;
begin
  Result:= False;
  
  try
    if FDConnection.Connected then
    begin
      Q:= TFDQuery.Create(nil);
      Q.Connection:= FDConnection;
      try
        Q.SQL.Text := 'select 1 from dual';
        Q.Execute;
        Result:= True;
      except
        on E: exception do
        begin
          Result:= False;
          try
            FDConnection.Open;
            Result:= True;
          except
          end;
        end;
      end;
      Q.Free;
    end
    else
    begin
      FDConnection.Open;
      if FDConnection.Connected then
      Result:= True
      else Result:= False;
    end;
  except
    on E: exception do
    begin
      WriteErrorLog(e.Message);
    end;
  end;
end;


В документации я читал, что можно проверять соединение c помощью Ping, выставлять у коннекции автоподключение, но вроде бы, где-то читал ))), что это не дает 100% результата восстановления соединения. Как бы вы проверяли связь?
20 апр 18, 16:03    [21355224]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 29230

20.04.2018 16:03, cptngrb пишет:
> В документации я читал, что можно проверять соединение c помощью *Ping*

это в какой?

Posted via ActualForum NNTP Server 1.5

20 апр 18, 16:38    [21355376]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
Мимопроходящий, вот такой
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Recovering_Connection_(FireDAC)
20 апр 18, 16:51    [21355422]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10598
cptngrb
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Recovering_Connection_(FireDAC)
Known limitations:

DBMSDescription
Advantage DatabaseNot supported for a local free connection.
dbExpress bridge driverFireDAC may fail to detect ekServerGone. Ping method is not supported.
InformixRequired to set DirectExecute to True.
Microsoft AccessNot supported.
MySQLTo minimize call delays when the network connection is lost, consider adjusting the ReadTimeout and WriteTimeout connection definition parameters.
ODBC bridge driverFireDAC may fail to detect ekServerGone. The Ping method is not supported.
SQLiteNot supported.
20 апр 18, 17:13    [21355491]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
забыл сказать, что Oracle )
23 апр 18, 08:16    [21359533]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
vavan
Member

Откуда: Казань
Сообщений: 3163
cptngrb, ощущение что пытаешься построить свой велосипед при том что он там уже встроен. попутно к сведению, обработку ошибок, включая в частности потерю (и восстановление) соединения там можно делать централизованно а не оборачивая каждый запрос отдельно
24 апр 18, 08:45    [21363084]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
schi
Member

Откуда: Москва
Сообщений: 2601
За except end руки уже оторвали ?
24 апр 18, 12:48    [21363948]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
vavan, это как?
24 апр 18, 15:07    [21364788]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
schi, можно было бы писать в лог, но пока не хочу
24 апр 18, 15:09    [21364804]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
vavan
Member

Откуда: Казань
Сообщений: 3163
cptngrb
это как?
что именно "как"?
25 апр 18, 09:41    [21366741]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
vavan,
автор
там можно делать централизованно а не оборачивая каждый запрос отдельно
25 апр 18, 11:35    [21367166]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
vavan
Member

Откуда: Казань
Сообщений: 3163
cptngrb, у многих компонент в anydac есть OnError, а у некоторых еще и OnRecover если уж встроенный функционал по восстановлению соединения и повторному выполнению не вполне устраивает. он конечно тоже с ошибками но возможно в свежих версиях получше работает, у меня увы заброшенная без права на апгрейд
25 апр 18, 11:50    [21367229]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
Linux. Oracle. х64. Консольное приложение.
Решил перейти на пул соединений. Для этого нужно создать пул

procedure CreateConnectionDef(const AName, AUser, APassword, AConnectStr: string; const APool: boolean; const ACountMax: integer);
var
  ConnectionDef: IFDStanConnectionDef;
begin

  ConnectionDef:=FDManager.ConnectionDefs.AddConnectionDef;
  ConnectionDef.Params.Clear;
  ConnectionDef.Name:= AName;
  ConnectionDef.Params.UserName:= AUser;
  ConnectionDef.Params.Password:= APassword;
  ConnectionDef.Params.Database:= AConnectStr;
  ConnectionDef.Params.DriverID:= 'Ora';

  if APool then begin
    FDManager.ConnectionDefs.ConnectionDefByName(AName).Params.Pooled := True;
    FDManager.ConnectionDefs.ConnectionDefByName(AName).Params.PoolMaximumItems := ACountMax;
  end;
end;


При запуске приложения

FDPhysOracleDriverLink1.NLSLang:= 'AMERICAN_AMERICA.CL8MSWIN1251';
FDPhysOracleDriverLink1.VendorLib:= '/opt/oracle/instantclient_12_2/libclntsh.so';
FDManager.Close;
while FDManager.State <> dmsInactive do
Sleep(0);
FDManager.Open;
CreateConnectionDef(DefaultConDefNamePool, user_name, passwd, con_str, True, MAX_SESSION_COUNT);


Далее, в отдельном потоке
В конструкторе:
oConnection := TFDConnection.Create(nil);
oConnection.LoginPrompt:= False;
oConnection.ResourceOptions.SilentMode:= true;
oConnection.ResourceOptions.AutoReconnect:= true;


В Execute потока:
function TDBPacket.Connect2Server(AConnection: TFDConnection): boolean;
begin
  try
  AConnection.ConnectionDefName:= DefaultConDefNamePool;
  AConnection.Connected:= True; //ушел в себя приду не скоро
  except
     логирование - но нет записи
  end;
end;


Как я проверяю потерю соединения: запускаю приложение, устанавливаю соединение и выполняю запросы пару раз, отключаю
сетевое соединение, дожидаюсь ошибки соединения, включаю сетевое соединение и на AConnection.Connected:= True; приложение уходит в себя.
Подскажите люди добрые WHF?
3 сен 18, 09:39    [21662271]     Ответить | Цитировать Сообщить модератору
 Re: Reconnect FireDAC + Oracle  [new]
cptngrb
Member

Откуда:
Сообщений: 223
В общем, нормально работает при любых параметрах в Windows, а в Linux чтобы получить хоть какой-нибудь ответ после восстановления соединения я у коннекции выставляю:

AutoConnect:= False;
AutoReconnect:= False;


Ответ приходит хоть и не так быстро, но приходит.
6 сен 18, 16:23    [21667201]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить