ahhjgh
等级:
可用分等级:长工
总技术分:409
总技术分排名:40519
发表于:2009-06-12 08:41:137楼 得分:0
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false; ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free; if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end; 请问这里的time的interval是多少,还有 Timer2.Enabled := true; Timer3.Enabled := true;这里的time2,time3 起什么作用,还有,还有如何捕捉到异常再去执行procedure TForm2.Timer4Timer(Sender: TObject);
try
//...正常代码
except
on E:Exception do
begin
if Pos('连接失败',E.Message) > 0 then
ADOConn.Close; //关闭连接 //这里去执行这个time事件吗
end;
end;(* 这个事件,这个处理过程也会关闭ADOConnection1,如何没有保存的数据就没有了,能不能实现如果没有连接成功就会延迟10秒再连后如果成功再保存
等级:
可用分等级:长工
总技术分:409
总技术分排名:40519
发表于:2009-06-12 08:41:137楼 得分:0
这个问题我也碰到过,最后是这么解决的,检测过程贴出,你自己参考:
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
Timer2.Enabled := false;
Timer3.Enabled := false; ConnStr := Form1.ADOConnection1.ConnectionString;
tmpStrList := Common.SplitString(ConnStr,';');
ServerIp := tmpStrList.Values['Data Source'];
tmpStrList.Free; if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Timer2.Enabled := true;
Timer3.Enabled := true;
Except
end;
end;
end;
end;
end; 请问这里的time的interval是多少,还有 Timer2.Enabled := true; Timer3.Enabled := true;这里的time2,time3 起什么作用,还有,还有如何捕捉到异常再去执行procedure TForm2.Timer4Timer(Sender: TObject);
try
//...正常代码
except
on E:Exception do
begin
if Pos('连接失败',E.Message) > 0 then
ADOConn.Close; //关闭连接 //这里去执行这个time事件吗
end;
end;(* 这个事件,这个处理过程也会关闭ADOConnection1,如何没有保存的数据就没有了,能不能实现如果没有连接成功就会延迟10秒再连后如果成功再保存
目前我们主要使用TNewAdoCommand执行sql语句,TAdoConnection作为connection连接数据库.
TNewAdoCommand封装了TAdoCommand对象,通过NEWExecute调用过程Execute,一旦执行失败,
Execute会抛出异常,通过捕捉异常可以获得异常信息,从异常信息里判断是语句的语法错误还是
连接错误信息,因此我们只需要更改NewExecute就可以达到我们的目的。如下是具体的修改代码
A.需要在主线程的FormCreate和start时对 sReconnectConfig (需要重连的关键字)进行初始化,sReconnectConfig在define中定义,为全局变量
//20090311 zhuzc add for 数据库自动重连,数据库自动连接的时间间隔
dtConnectDelayTime := 1;
dtLastConnectTime := Now;
sReconnectConfigFile := extractFilePath(Application.ExeName);
if sReconnectConfigFile[length(sReconnectConfigFile)] <> '\' then
sReconnectConfigFile := sReconnectConfigFile + '\';
sReconnectConfigFile := sReconnectConfigFile + 'config.ini';
if not FileExists(sReconnectConfigFile) then
begin
sMsg := '警告:不存在配置文件' + sReconnectConfigFile + ' - reconnection,将无法实现重连数据库功能';
showErrorMsg(sMsg,sMsg);
end;
if FileExists(sReconnectConfigFile) then
LoadReconnectConfig(sReconnectConfigFile,sReconnectconfig);
B.在common中定义过程 LoadReconnectConfig 和 stringlistpos ,用于重连事件的文件加载及事件匹配,见common.pas C.重连函数如下
{
1.执行出现错误,识别错误为连接问题,这个通过stringlistpos函数来实现,连接问题的事件通过sReconnectConfig来获取
2.检查是否到下次连接时间,没有则退出,必须考虑频繁重新连接的问题.
3.重连
4.重连成功,dtLastConnectTime:= now,dtConnectDelayTime:=1; 这时候需要恢复重连时间为1
5.重连不成功; dtLastConnectTime := now;dtConnectDelayTime := dtConnectDelayTime * 2;if dtConnectDelayTime >= 60 then dtConnectDelayTime:= 60;
}
Sql版本:
function TNEWADOCommand.NEWExecute: _Recordset;
var
sError: string;
i: integer;
begin
//20090218 zhuzc add for 数据库断开自动重连
try
Result := Execute;
except
on E:exception do
begin
sError := E.message;
{if (pos('连接失败',sError) > 0)
or
(pos('不存在或拒绝访问',sError) > 0)
or
(pos('未指定的错误',sError) > 0)
or
(pos('Connection is busy with results for another ',sError) > 0) then }
if stringlistpos(sReconnectConfig,sError) > 0 then
begin
if now >= dtLastConnectTime + dtConnectDelayTime/60.0/60.0/24.0 then
begin
dtLastConnectTime := now;
Connection.Close;
try
Connection.Open;
dtConnectDelayTime:=1;
sError := sError + ',数据库重连成功';
except
on E1:exception do
begin
dtConnectDelayTime := dtConnectDelayTime * 2;
if dtConnectDelayTime >= 60 then
dtConnectDelayTime := 60;
// dtConnectDelayTime := 1;
sError := sError + ',再次重连数据库失败:' + E1.message + ',下次重连延时:' + IntToStr(dtConnectDelayTime) + '秒';
end;
end;
end;
end;
raise Exception.Create(sError);
end;
end;
if Connection.Errors.Count > 0 then
begin
for i := 0 to Connection.Errors.Count - 1 do
sError := sError + Connection.Errors.Description;
raise Exception.Create(sError);
end;
end;
这个行不
procedure TForm2.Timer4Timer(Sender: TObject);
var
strError:string;
ConnStr,ServerIp:string;
tmpStrList :TStringList;
Const
CONNECTABORT_SQLSERVER1 = '08S0 '; //连接失败的错误号(SQLSERVER) 在简体版本下,显示不出最后一位
CONNECTABORT_SQLSERVER2 = '08S01'; //连接失败的错误号(SQLSERVER)
CONNECTFAULT_SQLSERVER = '08001'; //连接不上服务器的的错误号(SQLSERVER)
begin
if Form1.ADOConnection1.Errors.Count >0 then
begin
strError := Form1.ADOConnection1.Errors.Item[0].SQLState;
if (strError = CONNECTABORT_SQLSERVER1)or(strError = CONNECTABORT_SQLSERVER2)or(strError = CONNECTFAULT_SQLSERVER) then
begin
ConnStr := Form1.ADOConnection1.ConnectionString; //获得数据库所在服务器的IP地址
tmpStrList := Common.SplitString(ConnStr,';'); //获得数据库所在服务器的IP地址
ServerIp := tmpStrList.Values['Data Source']; //获得数据库所在服务器的IP地址
tmpStrList.Free; //获得数据库所在服务器的IP地址 if PingServer(ServerIp) then
begin
Form1.ADOConnection1.Connected := false;
Try
Form1.ADOConnection1.Open;
Except
end;
end;
end;
end;
end;
ADOQUERY1.Connection:=nil;
try
adoConnection1.Close;
adoConnection1.Open;
ADOQUERY1.Connection:=adoConnection1;
ADOQUERY1.UpdateBatch();
except
showMessage(GetErrorInfo); //提示出错信息
end;不知道这种方法能不能保存数据,我试试
如果你在保存数据时断线了,那么无论有没有写我这段检测代码,你都是无法成功保存数据的.但是如果没有这段检测代码,那么你这个AdoConnection的Connectioned属性就永远为true了(事实上,他已断开),除非你重起你的程序,加了我这断代码后,就能检测到AdoConnection的假连接状态,并恢复正常!我认为已经很明白了,不知道你还有什么疑问呢?
try
adoConnection1.Close;
adoConnection1.Open;
ADOQUERY1.Connection:=adoConnection1;
ADOQUERY1.UpdateBatch();
except
showMessage(GetErrorInfo); //提示出错信息
end;
用这种方法解决不少问题
现在最后有个问题,如果保存时网断还是会提示一般网络问题,请查看文档,能不能提示,网络连接失败,请稍后
try
ADOQUERY1.Connection:=adoConnection1;
ADOQUERY1.UpdateBatch();
except
showMessage(GetErrorInfo); //提示出错信息
end;
网络通自然执行成功,不通的话,再怎么重连还是不成功,而且还会产生尝试连接数据库的延时
你说的很对,所以我每次还是ping一样网络,如果成功就不必要,如果不成功就再执行以上代码我试了网络断开了,你用try也不行,还是提示一般性网络问题,我试了,