服务端连接数据库正常,但客户端有时正常,有时就连接不上,但服务端和客户端的UDP通讯正常。客户端连接不正常时出现"dbnetlib connectionread[(recv().)]一般性网络错误" , 比较奇怪的是客户端并不是每次都连接不上, 只是偶尔, 而且出现问题的客户端不固定. 客户端数量 50 台环境: Delphi7 + SQL Server 2000(SP4), 客户端xp, 服务器端 xp, 数据库服务器 WINDOWS2003我在客户端有一个测试连接数据库的函数, 服务端发送命令, 客户端便尝试连接, 如果出错则将错误信息通过 UDP 返回给服务端.对于该问题, 我在大富翁上找到如下解决方法:
//_____________________________________________________________________
大富翁:ID=1097834
用ADO连接SQL SERVER出错,第一次连接正常,第二次出错,再连又正常,如此反复
猛禽 (2002-05-14 16:11:00)
终于解决了,原来是ADOConnection需要唯一标识,否则SQL Server会进行缓存。 shuizi2000 (2002-11-18 10:27:00)
To:猛禽
你是怎么做的呀?怎么做ADOConnection的唯一标识?谢谢 猛禽 (2002-11-19 15:32:00)
在ConnectionString中指定Application Name,保有证每个Connection的Application Name
不相同即可
//_____________________________________________________________________我也试过了, 将每个客户端的Application Name 设置为本机IP地址, 这样不会有重复的了吧, 当还是出现. 曾见有高手说:
try
ADOConnection1.Connected := False;
ADOConnection1.Connected := True;
except
有问题
end;
我也试验过, 假如拔掉网线后再插上, 使用以上代码不会"有问题" ,但 ADOQuery 查询时会出错.下面我给出我测试数据库连接的函数:
function TfrmCoverBase.TestDatabaseConnection( blnSendToServer: boolean;
blnKeepConnection: boolean; Popwin: TfrmPopwin ): boolean;
var
i: integer;
frmPopwin: TfrmPopwin;
begin
result := false; if Popwin = nil then
frmPopwin := ShowPopWin('正在连接数据库,请稍候...',false)
else
begin
frmPopwin := Popwin;
frmPopwin.UpdateInfo('正在连接数据库,请稍候...');
end;
try
//测试连接是否断开
dmData.AConnServer.Connected := false;
try
dmData.AConnServer.Connected := true;//_____________通过错误信息发现,主要是这个地方出错
try
with dmData.qryTempS do
begin
Close;
SQL.Clear;
SQL.Add('SELECT GETDATE()');
Open;
Close;
result := true;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_INFO + '数据库连接测试成功');
frmPopwin.UpdateInfo('数据库连接测试成功');
end;
end;
except
dmData.AConnServer.Connected := false;
try
dmData.AConnServer.Connected := true;
except
on E: Exception do
begin
result := false;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_ERROR + '数据库连接测试失败:' + E.Message); //和下面Except的冒号不一样,以便考官端判断错误位置。
frmPopwin.UpdateInfo('数据库连接测试失败:' + E.Message);
end;
end;
end;
end;
except
on E: Exception do
begin
result := false;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_ERROR + '数据库连接测试失败:' + E.Message);
frmPopwin.UpdateInfo('数据库连接测试失败:' + E.Message);
end;
end;
end;
finally
if not blnKeepConnection then
dmData.AConnServer.Connected := false;
frmPopwin.AutoClose := true;
end;
end;
这个问题困扰了我快一年了, 不知道大家是否遇到过类似的问题
//_____________________________________________________________________
大富翁:ID=1097834
用ADO连接SQL SERVER出错,第一次连接正常,第二次出错,再连又正常,如此反复
猛禽 (2002-05-14 16:11:00)
终于解决了,原来是ADOConnection需要唯一标识,否则SQL Server会进行缓存。 shuizi2000 (2002-11-18 10:27:00)
To:猛禽
你是怎么做的呀?怎么做ADOConnection的唯一标识?谢谢 猛禽 (2002-11-19 15:32:00)
在ConnectionString中指定Application Name,保有证每个Connection的Application Name
不相同即可
//_____________________________________________________________________我也试过了, 将每个客户端的Application Name 设置为本机IP地址, 这样不会有重复的了吧, 当还是出现. 曾见有高手说:
try
ADOConnection1.Connected := False;
ADOConnection1.Connected := True;
except
有问题
end;
我也试验过, 假如拔掉网线后再插上, 使用以上代码不会"有问题" ,但 ADOQuery 查询时会出错.下面我给出我测试数据库连接的函数:
function TfrmCoverBase.TestDatabaseConnection( blnSendToServer: boolean;
blnKeepConnection: boolean; Popwin: TfrmPopwin ): boolean;
var
i: integer;
frmPopwin: TfrmPopwin;
begin
result := false; if Popwin = nil then
frmPopwin := ShowPopWin('正在连接数据库,请稍候...',false)
else
begin
frmPopwin := Popwin;
frmPopwin.UpdateInfo('正在连接数据库,请稍候...');
end;
try
//测试连接是否断开
dmData.AConnServer.Connected := false;
try
dmData.AConnServer.Connected := true;//_____________通过错误信息发现,主要是这个地方出错
try
with dmData.qryTempS do
begin
Close;
SQL.Clear;
SQL.Add('SELECT GETDATE()');
Open;
Close;
result := true;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_INFO + '数据库连接测试成功');
frmPopwin.UpdateInfo('数据库连接测试成功');
end;
end;
except
dmData.AConnServer.Connected := false;
try
dmData.AConnServer.Connected := true;
except
on E: Exception do
begin
result := false;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_ERROR + '数据库连接测试失败:' + E.Message); //和下面Except的冒号不一样,以便考官端判断错误位置。
frmPopwin.UpdateInfo('数据库连接测试失败:' + E.Message);
end;
end;
end;
end;
except
on E: Exception do
begin
result := false;
if blnSendToServer then
begin
Send(CMD_REPORT + CMD_REPORT_ERROR + '数据库连接测试失败:' + E.Message);
frmPopwin.UpdateInfo('数据库连接测试失败:' + E.Message);
end;
end;
end;
finally
if not blnKeepConnection then
dmData.AConnServer.Connected := false;
frmPopwin.AutoClose := true;
end;
end;
这个问题困扰了我快一年了, 不知道大家是否遇到过类似的问题
解决方案 »
- 求讲indy的书~~
- 通过adotable的loadfromfile从xml文件读取数据,如何可以比较高效的把数据保存入数据库
- delphi关于hint、messagedlg等几个问题求助,在线等。。
- 关于TDataModule的问题
- 急! !急! !急! ! 如何用Delphi 代码修改PC的DNS,必要时并使PC的DNS设置那变灰使用户无法修改 .
- 急!建立控件数组的疑惑!
- *******还是sql数据库的恢复问题,老问题了,可是还是没有成功*******
- 那里有InstallShield Express for delphi5下载?
- 这个sql语句怎么写啊??
- 你的DELPHI6的帮助有没有这种问题?
- 如何将一个整型数强制转让成浮点数?
- SPCOMM 接收数据不完整!
halfdream(哈欠) (****) 信誉:144每次有人找我问起楼主那个经典问题,我都是同样的回答..
可几乎每次问问题的人总以为我在开玩笑.当数据库连接断开时,这时候需要做什么呢?是试图重连?不断检查连接状态?
NO! 不要这样做!
数据库为什么断开?多半网络问题或者数据库当机或重启.事实上,这时候试图程序自动重连,
毫无意义!这样做反而会为负担很重的网络更没有恢复的机会.这时候该做什么? 是的,释放连接对象,很多封装底层连接的组件,都会暂存连接状态,
当底层实际连接失败,封装对象的状态却是连接正常,这时候,连接不可能得到恢复.
怎么让封装对象与底层连接状态一致? 很简单,让连接对象CLOSE!怎么知道连接失败? 在对数据库操作时! 对于VCL,组件会扔出数据库类型的异常,要做的,就是抓住它.对于使用数据感知控件,在Application.OnException事件中也可以得到它.
在处理这样异常时,就按刚才说的那样,"让连接对象CLOSE"!对于状态为CLOSE的连接对象,不需要再操心什么.在使用VCL封装Ado时,当连接对象AdoConnection状态为关闭时,任何一个数据库的操作,它都会自动去连接.这是缺省的属性设计.
----------------针对我的问题, 我请教一下:-------------------
这时候该做什么? 是的,释放连接对象,很多封装底层连接的组件,都会暂存连接状态,
当底层实际连接失败,封装对象的状态却是连接正常,这时候,连接不可能得到恢复.
怎么让封装对象与底层连接状态一致? 很简单,让连接对象CLOSE!
-------- 是说 将 dmData.AConnServer.Connected := false; 改为
dmData.AConnServer.Close; 吗?
对于状态为CLOSE的连接对象,不需要再操心什么.在使用VCL封装Ado时,当连接对象AdoConnection状态为关闭时,任何一个数据库的操作,它都会自动去连接.这是缺省的属性设计.
-------- 假如我每次用完后 Close, 下次查询时是否不需要 Open 或 Connected := true;
AConnServer.Connected := false; 与 AConnServer.Close 的区别
AConnServer.Connected := true; 与 AConnServer.Open 的区别