如何将2个IBDatabase设置为1个IBTransaction?

时间:2015-05-05 21:50:15

标签: delphi transactions database-connection

我在DataModule中有一个与我的IBTransaction链接的IBDatabase 在项目的一个模块中,我需要控制两个数据库中的持久性。

为此,我以这种方式添加第二个IBDatabase:

constructor TConnections.Create(AIBDatabase: TIBDatabase);
begin
  if AIBDatabase = nil then
    raise Exception.Create('The base connection is needed!');
  inherited Create;
  FIBDatabase := TIBDatabase.Create(nil);
  FIBDatabase.LoginPrompt := false;
  FIBDatabase.Params.Clear;
  FIBDatabase.Params.Text := AIBDatabase.Params.Text;
  FIBDatabase.DatabaseName := AIBDatabase.DatabaseName.Replace('DB.GDB', 'DB2.GDB');
end;

procedure TConnections.SetTransaction(AIBTransaction: TIBTransaction);
begin
  if AIBTransaction = nil then
    raise Exception.Create('Then Transaction is needed!');
  AIBTransaction.AddDatabase(FIBDatabase);
  FIBDatabase.DefaultTransaction := AIBTransaction;
  FIBDatabase.Open;
end;

任何选择命令都可以正常工作,但在插入命令中会发生错误 好吧,我有这个:

connections := TConnections.Create(Dm.Database);
try
  connection.SetTransaction(Dm.Transaction);

  qry := TIBQuery.Create(nil);
  qry.Database := Dm.Database;
  try
    // here are commands with Dm.Transaction
    // ...
    qry.ExecSql;
  finally
    qry.Free;
  end;

  otherQry := TIBQuery.Create(nil);
  otherQry.Database := connection.OtherDatabase;
  try
    // here are commands with connection.OtherDatabase but same Transaction
    // ...
    otherQry.ExecSql;  // The error occurs here.
  finally
    otherQry.Free;
  end;

  Dm.Transaction.Commit;
finally
  connection.Free;
end;
  

'无效的交易句柄(期望明确的交易开始)'

这些块包含在try except中 因此,如果我再次尝试,在错误发生后,该过程将顺利进行。

我的配置有什么问题?

1 个答案:

答案 0 :(得分:1)

如果您明确启动了事务,可能会发生这种情况。必须明确地完成每个显式事务。因此,如果您的连接是明确打开的,则应明确关闭它。

您可以使用:

//Commit(Stop) the transaction before open an other connection
if Dm.Transaction.InTransaction then 
  dm.Transaction.Commit;
  

注意:在将InterBaseExpress数据集连接到客户端数据集的应用程序中,每个查询都必须位于自己的事务中。您必须为每个查询组件使用一个事务组件。

http://docwiki.embarcadero.com/Libraries/XE8/en/IBX.IBDatabase.TIBTransaction