Компоненты ADO CommandTimeout

У меня проблема с настройками таймаута выполнения запроса с TADOQuery, TADOCommand или TADODataSet (я пробовал это с каждым). У меня есть маленькое приложение, которое подключается к базе данных и периодически выполняет хранимые процедуры, которые возвращают dataset в результате. Моя цель-держать это приложение всегда в сети, но моя проблема в том, что когда соединение потеряно, тайм-аут только что выполненной команды (через один из упомянутых компонентов) принимает по умолчанию 30 секунд. Я искал решение, но ничего не работает. не могли бы вы дать мне совет, как установить CommandTimeout, например, на 5 секунд или лучше сказать, как изменить ADODB.pas за уважение моего собственного тайм-аута, пожалуйста ?

для этого было много "решений", таких как set DataComponent.Соединение.CommandTimeout: = 1; но на самом деле ничего не работает. Я использую D2009, MSSQL2005, и соединение вместе с компонентом данных создается динамически в нитка.

последнее, что я пробовал это

// protected variable owned and created in the thread with its own connection
var Query_Object: TADODataSet; 

// connection timeout is set to 3 seconds
Query_Object.Connection.ConnectionTimeout := 3;
...

// this piece of code I'm calling periodically in the only one existing thread
...
SQL_Query := 'EXEC my_procedure_which_returns_dataset'

with Query_Object do
  begin
    Close;    
    CommandType := cmdText;
    CommandText := SQL_Query;
    CommandTimeout := 5;             // doesn't affect the timeout
    CursorLocation := clUseServer;   // let the dataset retreives prepared data
    Open;
  end;

// and here I need to get faster than in the default 15 seconds to let the user
// know that the reading takes more than mentioned 5 seconds
...

Спасибо большое :)

3 ответов


CommandTimeout срабатывает, когда у вас есть длительные запросы. Есть CommandTimeout собственность TADOConnection но это не работает. Вы должны использовать CommandTimeout на .

если сервер недоступен, ваш вопрос говорит "соединение потеряно", вам нужно указать ConnectionTimeout на


ниже то, что мы используем, чтобы установить тайм-аут 300 для наших длительных отчетов.

  //***** Fix setting CommandTimeOut. 
  //      CommandTimeOut "should" get the timeout value from its connection. 
  //      This is not supported in ADODB (using Delphi5)
  TADODataSet(qryReport).CommandTimeout := ADOConnection.CommandTimeout;

редактировать

выполнение следующего фрагмента кода на моей машине разработки истекает через 1 секунду.

  • запрос имеет connectionstring к нашей производственной базе данных SQLServer.
  • сценарий (пытается) работает в течение 10 секунд
  • через секунду я получаю тайм-аут исключение

тест

procedure TForm1.btn1Click(Sender: TObject);
const
  SSQL: string =
    'DECLARE    @intLoop int '#13#10
    + 'SET @intLoop = 10 '#13#10
    + 'WHILE @intLoop > 1 '#13#10
    + 'BEGIN '#13#10
    + ' SELECT  @intLoop, GetDate() '#13#10
    + ' WAITFOR DELAY ''00:00:01'' '#13#10
    + ' SELECT  @intLoop = @intLoop -1 '#13#10
    + 'END ';
begin
  qry1.SQL.Text := SSQL;
  TADODataSet(qry1).CommandTimeout := 1;
  qry1.ExecSQL;
end;

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

type 
TADOQueryHack = class(TADOQuery);

...

TADOQueryHack(Qry).CommandTimeout := COMM_TIMEOUT;