最好是一句句的写入
否则用 begin tran 吧

解决方案 »

  1.   

    老兄,很好解决的,换一个方式。
    记住:对数据库的所有操作最好用SQL语句实现,不要用delphi中query\table\等提供的如:table.insert\query.append等一类,能气死你,delphi在这方面做的太差了。但如果全部用SQL语句,就太简单了。最多加一个事务处理。
    OK,回去解决了吧。看来今天不用加班了。回家陪女朋友吧。
      

  2.   

    对了,必须用事物!但是你用的是ADO控件。那你要用事物(Transaction)只能在数据库里用了!
      

  3.   

    请大家看看我上面列的两个联接,就知道我为什么极力反对使用Delphi的事务处理我想知道数据集本身有没有隐含的事务机制。为什么ADOQuery.UpdateBatch(arAll);还能给我提交一条?
      

  4.   

    三层数据库主细表数据有那么复杂吗?Delphi做得很好啊,用不着我们考虑那么多。关于事务的问题,在provider里面有相关的处理,我们并不需要考虑。现在我们的做法是在中间层根据附表的个数生成相应的ADODataSet,然后动态的给主表和附表ADODataSet的CommandText属性和masterfield、indexfield属性赋值,建立对应关系,获取数据后传给客户端。
    一两句说不清楚,你给我个邮箱,我给你发过去。
      

  5.   

    to hzb(Explorer) :  大侠,在下感激涕零!谢谢先!mailto:[email protected]
      

  6.   

    你并没有开启事务,数据当然提交进去了,你只不过开启了ADOQUERY的缓存功能;
     if not  ADOCONNECTIONG.InTransaction then dm.adoc.BeginTrans ;
     Try    
         主表.UpdateBatch(arAll);
         子表.UpdateBatch(arAll);
         ADOCONNECTIONG.CommitTrans;
     except
        ADOCONNECTIONG.RollbackTrans;//存盘失败!
     end;
      

  7.   

    顺便问一句:三层系统中,可以使用ADOCONNECTIONG的事务吗?
      

  8.   

    问题是,你真的设置好了ADO的缓冲了吗?要让ADO缓冲起来,必须设置下面的属性:
    with TADODataSet do begin
      CursorLocation := clUseClient;
      CursorType := ctStatic;
      LockType := ltBatchOptimistic;
      CommandType := cmdText;
      CommandText := 'SELECT * FROM Employee';
      Open;
    end;
    此后,你可以对数据进行操作,操作完成之后,可以使用UpdateBatch和CancelBatch。
      

  9.   

    具体的,请参看Delphi的帮助系统:Using batch updates
      

  10.   

    kingron你以前不是不搞DB的吗?
      

  11.   

    使用缓存更新试试!cached updates 。When you apply updates for master/detail tables, the order in which you list datasets to update is significant. Generally you should always update master tables before detail tables, except when handling deleted records. In complex master/detail relationships where the detail table for one relationship is the master table for another detail table, the same rule applies.
    You can update master/detail tables at the database or dataset component levels. For purposes of control (and of creating explicitly self-documented code), you should apply updates at the dataset level. The following example illustrates how you should code cached updates to two tables, Master and Detail, involved in a master/detail relationship:Database1.StartTransaction;try
      Master.ApplyUpdates;
      Detail.ApplyUpdates;
      Database1.Commit;
    except
      Database1.Rollback;
      raise;
    end;
    Master.CommitUpdates;
    Detail.CommitUpdates;If an error occurs during the application of updates, this code also leaves both the cache and the underlying data in the database tables in the same state they were in before the calls to ApplyUpdates.
    If an exception is raised during the call to Master.ApplyUpdates, it is handled like the single dataset case previously described. Suppose, however, that the call to Master.ApplyUpdates succeeds, and the subsequent call to Detail.ApplyUpdates fails. In this case, the changes are already applied to the master table. Because all data is updated inside a database transaction, however, even the changes to the master table are rolled back when Database1.Rollback is called in the except block. Furthermore, UpdatesMaster.CommitUpdates is not called because the exception which is re-raised causes that code to be skipped, so the cache is also left in the state it was before the attempt to update.To appreciate the value of the two-phase update process, assume for a moment that ApplyUpdates is a single-phase process which updates the data and the cache. If this were the case, and if there were an error while applying the updates to the Detail table, then there would be no way to restore both the data and the cache to their original states. Even though the call to Database1.Rollback would restore the database, there would be no way to restore the cache.
      

  12.   

    牛人露面了,不过我宣布,牛人的回答避开了我的问题!经测试得出:ADO的UpdateBatch方法并没有隐含事务机制,而ADOConnection的事务机制又存在缺陷,天哪!完了,我还是回家...
      

  13.   

    1、主表不做缓存更新,而从表做。
    2、用TADOQuery,但不连接主从表关系。
    从表的SQL内容是:SELECT * FROM 从表 WHERE 连接字段名=:查询参数名(当然,你也可以不加条件,而用Filter来进行)
    在主表的afterScroll事件中写代码,当主表记录指针移动时,设从表查询参数值为主表的与从表的连接字段值,并Requery。而当从表新增记录时,手工给从表对应的连接字段赋值。
      

  14.   

    得出结论:  如果我不使用ADO的事务处理,此问题无法解决。还是结账吧!