我的应用程序的每个工作线程都在远程SQL Server数据库上执行大量UPDATE
操作。我使用for..do
构造迭代记录集,其中包含用于进一步更新的输入数据:
try
for i := 0 to RS.RecordCount-1 do
begin
// omitting the quotes for brevity
CN.Execute('my_stored_proc ' + RS.Fields['Dummy'].Value);
RS.MoveNext;
end;
except
on E: Exception do
begin
// At the moment here is a simple notice of the exception thrown
ShowMessage(E.ClassName + ': ' + E.Message);
end;
我注意到EOleException
=“查询超时已到期”时,E.Message
经常被引发。这显然意味着线程等待SQL Server响应然后中止当前请求。然后(根据日志),线程提交新的i
值,忽略前一个值。因此,如果EOleException
抛出i = 613
处理程序只是移动到i = 614
并继续工作而留下613处女。
我的问题是:
处理此类异常的正确方法是什么,确保所有记录都会被处理,即使它们导致异常几片回来?
我应该选择while..do / repeat..until
构造,我只能在处理程序中Dec(i)
,还是有更多不拘一格的技术?
答案 0 :(得分:1)
如果Execute()
引发异常,您显示的代码将不会处理下一条记录。而是退出整个循环。要做你想要的,你需要处理循环内部的异常,而不是在外面。
您也不应该使用RecordCount
属性。请改用Eof
属性。
试试这个:
try
while not RS.Eof do
begin
try
// omitting the quotes for brevity
CN.Execute('my_stored_proc ' + RS.Fields['Dummy'].Value);
except
on E: EOleException do
begin
if E.Message = 'Query timeout expired' then
Continue;
raise;
end;
end;
RS.MoveNext;
end;
except
on E: Exception do
begin
// At the moment here is a simple notice of the exception thrown
ShowMessage(E.ClassName + ': ' + E.Message);
end;
end;