客户端数据集的ADS错误5047

时间:2014-06-26 09:35:47

标签: delphi delphi-7 advantage-database-server tclientdataset

报告问题:

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;

0 个答案:

没有答案