经典的判断数据库连接断开或网络断开问题

本文介绍了一种处理数据库连接断开的有效方法,通过定时检查网络和数据库连接状态,并在发生异常时释放连接对象,确保应用程序稳定运行。

我们这里的软件遇到这个问题,解决的办法是,每次用数据库的时候都把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

在C语言中,为了判断数据库连接是否断开,主要依赖于所使用的数据库API库。常见的库如MySQL的libmysqlclient、SQLite等都提供了一系列的API来处理连接的状态及错误信息。 ### MySQL (libmysqlclient) 示例 当使用MySQL API进行数据库连接时,一般通过以下步骤来进行连接检测: #### 初始化连接 首先初始化数据库连接库: ```c #include <mysql.h> #include <stdio.h> int main() { MYSQL *conn; conn = mysql_init(NULL); if (!conn) { printf("Error initializing connection.\n"); return 1; } } ``` #### 连接数据库 然后尝试连接数据库: ```c if (mysql_real_connect(conn, "localhost", "username", "password", "database", 0, NULL, 0) == NULL) { fprintf(stderr, "%s\n", mysql_error(conn)); mysql_close(conn); return 1; } ``` #### 检查连接状态 一旦连接建立,你可以通过以下方法检查数据库连接是否仍然有效: ```c while (mysql_errno(conn) != 0) { // 如果mysql_errno(conn) 返回非零值,说明出现了错误 printf("Connection error: %s\n", mysql_error(conn)); mysql_close(conn); // 关闭连接并结束程序 return 1; } printf("Connected to database successfully.\n"); // 进行数据库操作... mysql_close(conn); // 结束数据库操作后关闭连接 return 0; ``` ### SQLite 示例 SQLite相对简单,它的错误码存储在 `sqlite3_errcode` 和 `sqlite3_lasterr` 中,可以通过以下方式检查错误: ```c #include <sqlite3.h> int main() { sqlite3 *db; int rc; rc = sqlite3_open("test.db", &db); if (rc != SQLITE_OK) { // 如果返回值不是 SQLITE_OK,说明发生了错误 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return 1; } else { printf("Opened database successfully.\n"); } // 进行数据库操作... sqlite3_close(db); // 关闭数据库连接 return 0; } ``` 在这两个例子中,关键点在于使用错误检查函数来确认连接是否正常。如果连接过程中出现错误,相应的错误消息会被打印出来,并且最终关闭连接。正确的错误处理流程可以帮助开发者更有效地调试问题,并保证程序的健壮性和稳定性。 --- ## 相关问题: 1. 如何使用 libpq 库在 PostgreSQL 数据库中进行连接检测? 2. C语言中如何利用ODBC库进行数据库连接状态的检查? 3. 当使用 Microsoft Access Excel 的 OLE DB 接口进行数据库交互时,如何检测连接是否中断?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值