读书人

:数据高峰期时创建ADOQuery失败

发布时间: 2012-12-16 12:02:32 作者: rapoo

求救:数据高峰期时,创建ADOQuery失败
有两个工作线程A和B,在程序运行期间,每接收到一次数据请求,就调用函数ExecuteQuery,往同一个数据库表ws_source里写数据。任一个线程调用ExecuteQuery时,都会动态创建一个临时的TADOConnection对象,执行SQL完毕之后,再将它释放。
/// <summary>
/// 执行返回受影响的行数
/// </summary>
function ExecuteNoQuery(ACommandText:string):Integer;var
Query: TADOQuery;
ADOConnection : TADOConnection;
begin
ADOConnection := GetConnection();
try
Query := TADOQuery.Create(Application); // 问题:数据高峰时,会发生创建失败
try
With Query do
begin
Connection := ADOConnection;
Close;
SQL.Clear;
SQL.Add(ACommandText);
try
Result := ExecSQL;
except
on E:EOleException do
begin
// 如失去连接则重新连接
if (CompareText(E.Message,'Connection failure')=0) or
(CompareText(E.Message,'连接失败')=0) then
begin
ADOConnection.Connected := False;
ADOConnection.Connected := True;
Result := ExecSQL;
end
else
begin
raise;
end;
end
else
begin
raise;
end;
end;
end;
finally
Query.Free;
end;
finally
ReleaseConnection(ADOConnection);
end;
end;


现在的问题是,一般在每天的早上9点~10点会有一次数据高峰期,这时就会频繁发生TADOQuery创建失败的情况,导致数据无法写入数据库。
[最优解释]
可能是 数据冗余了吧

[其他解释]
把错误捕获出来,然后再看如何解决,
[其他解释]
有个想法:在程序启动的时候,创建一个全局的TADOQuery对象,供那两个工作线程使用,在程序关闭的时候再销毁它。因为它被两个工作线程共同使用,所以要加资源保护锁。
因为,程序里还有其他的线程要访问这个数据库的其他表,其他线程会不会因为程序运行期间始终存在一个全局TADOQquery对象,而无法创建另外的TADOQquery对象?
------其他解决方案--------------------


尝试了一下加入重试机制,当创建TADOQquery失败时,重新调用ExecuteQuery,最多允许5次重试。结果在5次里面竟然还是没有一次成功。郁闷啊。
[其他解释]
这个问题很严重啊,一个早上就丢掉了10多万条数据
[其他解释]
捕获到的错误如下:
Access violation at address 00490057 in module 'MonitorServer.exe'. Read of address F1751E1D
不知道从这里能看出什么呢?
[其他解释]
这几天查了很多资料。
看到网上这么说(链接地址http://www.myexception.cn/delphi/264643.html):ADOQquery.Free后,由于ADO本身的特性,这个ADOQquery对应的数据库连接要过一段时间才会被释放掉。如果在短时间内大量地创建和释放ADOQquery,就会有大量的数据库连接来不及释放掉,导致后面无法创建ADOQquery。当数据高峰过后,堆积的数据库连接会逐渐被释放掉,所以后面又可以创建ADOQquery了。

这个说法,很好解释了我的问题。但如何解决这个问题呢?
[其他解释]
高手呢?来分析一下啊
[其他解释]

引用:
这几天查了很多资料。
看到网上这么说(链接地址http://www.myexception.cn/delphi/264643.html):ADOQquery.Free后,由于ADO本身的特性,这个ADOQquery对应的数据库连接要过一段时间才会被释放掉。如果在短时间内大量地创建和释放ADOQquery,就会有大量的数据库连接来不及释放掉,导致后面无法创建ADOQquery。当数据高峰过后,堆积……


不要繁的建和放就行了。

[其他解释]
呵,帮你结贴。。
[其他解释]
引用:
引用:
这几天查了很多资料。
看到网上这么说(链接地址http://www.myexception.cn/delphi/264643.html):ADOQquery.Free后,由于ADO本身的特性,这个ADOQquery对应的数据库连接要过一段时间才会被释放掉。如果在短时间内大量地创建和释放ADOQquery,就会有大量的数据库连接来不及释放掉,导致后面无法……


多谢两位。
后来把这问题解决了。
频繁地创建和释放是没关系的,主要是“Query := TADOQuery.Create(Application);
”这句有问题,因为创建TADOQuery的对象的Parent是Application,所以当手动释放时,一般要过一段时间才真正被释放。将它改为“Query := TADOQuery.Create(nil);
”,问题就解决了。
[其他解释]
该回复于2012-11-30 08:30:58被管理员删除

读书人网 >.NET

热点推荐