我们这里的软件遇到这个问题,解决的办法是,每次用数据库的时候都把connection和query打开一次,同时在界面上留有panel来提示网络断开还是数据库断开(下面两个函数是我们用来判断网络断开还是数据库断开的函数):
function CheckNetConnection(IP: string): Boolean;
var
Echo: TIdEcho;
begin
Echo := TIdEcho.Create(nil);
with Echo do
begin
try
Host := IP;
Connect(1000);
Result := True;
except
Result := False;
end;
end;
Echo.Free;
end;
function CheckDBConnection(IP: string): Boolean;
var
Telnet: TIdTelnet;
begin
Telnet := TIdTelnet.Create(nil);
try
with Telnet do
begin
if Connected then Disconnect;
Host := IP;
Port := 1433;//数据库服务用的端口号(Sql server使用这个端口号)
try
Connect(1000);
Result := True;
except //否则重连
Result := False;
end;
end;
finally
Telnet.Disconnect;
Telnet.Free;
end;
end;
上面两个函数在Timer中周期性检查,我们的timer时间间隔为10秒,显示稍微之后,不过客户能够容忍,另外断开网络的时候检索数据库还是偶尔卡一点,不过无需重起软件,只要处理网络和数据库就行了
每次有人找我问起楼主那个经典问题,我都是同样的回答..
可几乎每次问问题的人总以为我在开玩笑.
当数据库连接断开时,这时候需要做什么呢?是试图重连?不断检查连接状态?
NO! 不要这样做!
数据库为什么断开?多半网络问题或者数据库当机或重启.事实上,这时候试图程序自动重连,
毫无意义!这样做反而会为负担很重的网络更没有恢复的机会.
这时候该做什么? 是的,释放连接对象,很多封装底层连接的组件,都会暂存连接状态,
当底层实际连接失败,封装对象的状态却是连接正常,这时候,连接不可能得到恢复.
怎么让封装对象与底层连接状态一致? 很简单,让连接对象CLOSE!
怎么知道连接失败? 在对数据库操作时! 对于VCL,组件会扔出数据库类型的异常,要做的,就是抓住它.对于使用数据感知控件,在Application.OnException事件中也可以得到它.
在处理这样异常时,就按刚才说的那样,"让连接对象CLOSE"!
对于状态为CLOSE的连接对象,不需要再操心什么.在使用VCL封装Ado时,当连接对象AdoConnection状态为关闭时,任何一个数据库的操作,它都会自动去连接.这是缺省的属性设计.
同意楼上,也许我们考虑的楼上的意见以后可以解决我们软件仅有的一顿的问题,那样提示\重连\而且还不顿,就比较好了
TDataForm = class(TDataModule)
//...
procedure DataModuleCreate(Sender: TObject);
private
FOldApplicationOnException : TExceptionEvent;
procedure HandleException(Sender: TObject; E: Exception);
...
end.
procedure TDataForm.DataModuleCreate(Sender: TObject);
begin
...
FOldApplicationOnException := Application.OnException;
Application.OnException := HandleException;
end;
procedure TDataForm.HandleException(Sender: TObject; E: Exception);
begin
if E.ClassNameIs('EOleException') then
if ShowMsg(Screen.ActiveForm, format(
'数据库连接被意外中止,要重新连接吗?'#10#13+
'错误原因:%s',
[E.Message])) = IDYES then
begin
MainConn.Connected := False;
MainConn.Connected := True;
Exit;
end;
if Assigned(FOldApplicationOnException) then
FOldApplicationOnException(Sender, E)
end;
mark
我也遇到了类似的问题, 大家有时间看看
http://community.youkuaiyun.com/Expert/topic/5460/5460676.xml?temp=7.497805E-02