我需要檢測TAdoConnection組件何時與服務器失去連接。我試過使用OnDisconnect事件,但只有在調用Close方法或Connected屬性設置爲false時纔會觸發此事件。如何檢測到TadoConnection與服務器的通信中斷?
我使用TTimer和執行這樣的查詢
SELECT 1 RESULT FROM DUAL
在OnTimer事件
,抓住出現的任何異常嘗試另一種選擇。
是否有更好的選擇來檢測連接是否丟失?
我需要檢測TAdoConnection組件何時與服務器失去連接。我試過使用OnDisconnect事件,但只有在調用Close方法或Connected屬性設置爲false時纔會觸發此事件。如何檢測到TadoConnection與服務器的通信中斷?
我使用TTimer和執行這樣的查詢
SELECT 1 RESULT FROM DUAL
在OnTimer事件
,抓住出現的任何異常嘗試另一種選擇。
是否有更好的選擇來檢測連接是否丟失?
我看到DUAL表格。意思是說,你正在使用Oracle:
對於大多數(所有?)客戶端/服務器DBMS來說,沒有辦法檢測到連接丟失,除了要求DBMS進行某些操作。有很多原因,爲什麼連接丟失。可能是網絡故障,可能是...,可能是DBA關閉了一個DB。
許多DBMS API(包括Oracle OCI)都具有特殊功能,允許ping DBMS。 「ping」是對DBMS最小的可能請求。上面的SELECT需要比ping更多的工作。
但並非所有數據訪問組件(包括ADO)都允許使用DBMS API Ping調用來ping DBMS。然後你必須使用一些SQL命令。所以,上面的SELECT對於ADO是正確的。其他選項 - BEGIN NULL;結束;。它可能使用較少的DBMS資源(不需要優化器,不需要描述結果集等)。
TTimer確定。查詢應該在使用相應連接的線程中執行。雖然不是必須的,但它是一個不同的問題。
潛在的問題可能是在連接丟失時關閉連接。由於DBMS API可能處於失敗狀態,因此連接關閉可能會引發異常。
那種......
嗨大柔。如果我們在主線程中使用TADOConnection,我們應該從主線程「ping」sql嗎?我們是否也應該使用相同的TADOConnection或使用不同的「ping」TADOConnection? – zig 2015-06-24 12:41:57
@Dimitry答案很好。如果您的應用程序知道connectino是否丟失,TTimer方法(使用最少的操作)至關重要。
如果您只是想知道何時由於「失去通信」而導致語句失敗,則可以使用Application.OnException事件並檢查Exception屬性。
我以下面的代碼爲例,使用ApplicationEvents組件。只是一個草案的想法,不適合生產。
uses
ComObj;
procedure TForm2.ApplicationEvents1Exception(Sender: TObject; E: Exception);
var
EO: EOleException;
begin
if E is EOLEException then
begin
EO := EOleException(E);
//connection error (disconnected)
if EO.ErrorCode = E_FAIL then
begin
try
try
ADOConnection1.Close;
except
;
end;
ADOConnection1.Open;
ShowMessage('Database connection failed and re-established, please retry!');
except
on E:Exception do
ShowMessageFmt('Database connection failed permanently. '
+ 'Please, retry later'#13'Error message: %s', [E.Message]);
end;
end
else
ShowMessage(E.Message + ' ' + IntToStr(EO.ErrorCode));
end
else
ShowMessage(E.ClassName + #13 + E.Message);
end;
此致敬禮。
這是放棄ADO並使用DBX的原因之一。 Ado體系結構是基於服務器遊標的,並且此請求程序不會隨時丟失與服務器的連接。如果在某些情況下連接丟失,連接將無法重新啓動。另一方面,DBX由於其不連貫的架構,能夠重新連接到永遠。
這是不正確的。 ADO可以用作客戶端遊標的服務器,並允許應用斷開連接的數據集模型。從about.com: 爲了創建斷開連接的ADO記錄集,您必須首先將ADODataSets CursorLocation屬性設置爲「clUseClient」。然後打開Recordset。然後將ADODatasets連接設置爲無。不要關閉ADODataset。 – 2010-02-19 11:40:21
是ADO可以在公文包模式下工作。但DBX對這個問題的反應更自然,更可預測。 – 2010-02-19 20:58:56
我對連接池有同樣的問題。我開發了一個TADOSQLConnectionPool類來幫助重用線程DB工作的連接。當我想分配一個連接到一個線程時,我試圖通過運行最小的工作來檢查它是否健康,如「選擇1」。通過這種方式,我將確定連接。如果失敗,我將在下次請求時處理所有連接以重新創建。
SQL Server允許Qry.ExecSQL與SQL.Text =''作爲查詢(但不是'')。這可以每秒執行數百次。 – 2010-02-18 20:31:46