我是在中间层执行事务的,中间层用的是ODAC连接ORACLE(一个OraSession1,一个OraTable1,OraTable2,OraTable3,一个OraProvider1控件)我的事务是:有一个主表table1,两个从表table2,table3。当主表append一条记录时,两个从表也相应的插入一条记录,并把主表的ID写为自己的ID。如果出错了,那么就谁都不插入。我是在数据表OraTable1控件的BeforeInsert事件中激活事务的,不知是不是应该这样。我的程序如下:begin
 OraSession1.StartTransaction;  //开始事务;
 try
    OraTable2.Append;
    OraTable2.FieldValues['id']:=OraTable1.Fields[0].AsInteger;
    OraTable2.Post;
    OraTable3.Append;
    OraTable3.FieldValues['id']:=OraTable1.Fields[0].AsInteger;
    OraTable3.Post;
 except
   OraSession1.Rollback;   //出错则回滚
   OraTable1.CancelUpdates;//主表本身也取消插入
   exit;
 end;
 OraSession1.Commit;     //提交。结果是OraTable1表插入了记录,而另外两个表则没有相应的插入记录,就好象这段程序根本没有执行。
在这个事件中执行事务应该没有错吧?这里哪出错了呢?

解决方案 »

  1.   

    客户端:
    clientdataset1.append;
    clientdataset1.fieldbyname('id').asinteger:=1;
    clientdataset1.applyupdatas(0);
      

  2.   

    你用的ORACLE的直连控件,,还真不好说,,但是你说的情况我遇到过,,我的解决办法:
      全部,将APPEND EDIT;什么的 改成SQL语句来完成
      

  3.   

    应该在 DatasetProvider 的 BeforeUpdateRecord 事件中做吧
    begin
        OraTable2.Append;
        OraTable2.FieldValues['id']:=OraTable1.Fields[0].AsInteger;
        OraTable2.Post;
        OraTable3.Append;
        OraTable3.FieldValues['id']:=OraTable1.Fields[0].AsInteger;
        OraTable3.Post;
    end; 如果其中出错则会全部回滚
      

  4.   

    hiflower(花):
    但是我只在插入时使用事务,平时提交保存不用事务啊!
      

  5.   

    哦,明白了,有一个updatekind属性指明是哪种update.谢谢hiflower(花)
      

  6.   

    在DatasetProvider 的 BeforeUpdateRecord 事件中做还是不行啊,而且编译时有一个错误TCustomClientDataSet没有发现。
      

  7.   

    再请教:BeforeUpdateRecord事件中,是不是允许接收数据就把Applied设为true,拒绝就设为false?我在这个BeforeUpdateRecord事件过程中,两个从表倒是插入了,可是主表却没有APPEND成功,这是怎么回事?难道还要在BeforeUpdateRecord事件中,重新做table1.fieldvalues['字段1']:=DeltaDS.FieldValues['字段1'];
    table1.fieldvalues['字段2']:=DeltaDS.FieldValues['字段2'];
    table1.fieldvalues['字段3']:=DeltaDS.FieldValues['字段3'];
    ......
    不会这样麻烦吧?
      

  8.   

    回复人: 8341(八三四一) :如果你想让他们在同一个事务,首先必须保证PROVIDER的DATASET与中间的TABLE使用同一个数据库会话;
       另外应该在AFTERUPDATERECORD中写对子表的动作;在BEFOREUPDATERECORD中的APPLIED如是设为TRUE ,,provider 将不再负责这条记录的更新;
    这表示你已经自已处理了这条记录的更新;
      

  9.   

    对 Applied 要设为 False ,DataSetProvider 就会对 table1 更新