报告问题:
exception class : AdsError
exception message : Error 5047: The transaction command was not in valid sequence. Not in a transaction.
main thread ($918):
00607cc5 +07d Boxer.exe adscnnct 1576 +20 TAdsConnection.PerformRollback
00607d52 +002 Boxer.exe adscnnct 1606 +0 TAdsConnection.Rollback
0062eab5 +09d Boxer.exe DModule1 241 +10 TDM1.ApplyBoxer2Changes
违规代码:
procedure TDM1.ApplyBoxer2Changes;
begin
AdsConnection.BeginTransaction;
try
if cdsBoxes.ApplyUpdates(0) = 0 then
AdsConnection.Commit
else
raise Exception.Create('Record changed by another user.');
except
on e: Exception do
begin
AdsConnection.Rollback;
MessageDlg('An error occurred while attempting to save your changes:'+#13#10#10
+e.Message, mtError, [mbOK], 0);
cdsBoxes.CancelUpdates;
end;
end;
cdsBoxes.Refresh;
end;
其中cdsBoxes是连接到TDataSetProvider的TClientDataSet,其DataSet是具有相同AdsConnection = TDM1.AdsConnection的TAdsQuery,以及以下SQL:
SELECT * FROM Boxer2 WHERE Boxer1Id=:id
有人能看出这段代码有什么问题吗?
5047错误似乎表明在调用Rollback方法时事务不再处于活动状态。
我自己无法重现错误;在我的测试中,我能够添加,编辑和删除多个记录,然后提交所有更改或成功回滚。
更新:我已经能够重现它。当表中有2个相同的记录时会出现问题,因此无法识别要更新的记录(表中没有唯一键,DataSetProvider.UpdateMode = upWhereAll)。
我不确定为什么在这种情况下会自动取消交易,但至少提供用户友好消息的解决方法如下:
procedure TDM1.ApplyBoxer2Changes;
begin
AdsConnection.BeginTransaction;
try
if cdsBoxes.ApplyUpdates(0) = 0 then
AdsConnection.Commit
else
raise Exception.Create('Record changed by another user.');
except
on e: Exception do
begin
if AdsConnection.TransactionActive then
begin
AdsConnection.Rollback;
MessageDlg('An error occurred while attempting to save your changes:'+#13#10#10
+e.Message, mtError, [mbOK], 0);
end
else
begin
MessageDlg('A data integrity error occurred while attempting to save your changes.'+#13#10#10
+'Please report this to the help desk.', mtError, [mbOK], 0);
end;
cdsBoxes.CancelUpdates;
end;
end;
cdsBoxes.Refresh;
end;