在主进程和线程中都操作了数据库,子线程是重新创建连接来处理的,在这种情况下,想实现只要一个错误全部回滚,也就是事务的功能。或者这个问题也可以说和多线程无关,就是一个程序中创建了多个连接,在同时利用多个连接操作数据库的情况下,怎么实现事务功能?

解决方案 »

  1.   

    你的连接是DataSnap C/S,还是直接连接本地数据库。
      

  2.   

    用ado连的c/s数据库
      

  3.   

    事务处理需要利用Delphi的相关控件或数据库管理软件进行。它应是由数个SQL语句组成,要求同时正确执行。只要有一条失误,全部取消。
        楼主提出的方案,在不同的线程(不同的连接)中代码,构成事务,好象不可取。尚未见到实例。
    构成事务的几个SQL语句,是抱团执行,不好分割。建议利用ADO提供的事务处理功能adoconnection1.begintrans;         // 开始事务try  adoconnection1.execute(sqlstr1);  adoconnection1.execute(sqlstr2);  ...  adoconnection1.execute(sqlstrN);  adoconnection1.commitrans;       // 提交事务  showmessage('操作成功');except  adoconnection1.rollbacktrans;    // 事务回滚  showmessage('操作失败');end;
        如果需要线程,可以将上述代码装进一个线程中执行。
      

  4.   

    adoconnection1.begintrans;         // 开始事务
    try
      adoconnection1.execute(sqlstr1);
      adoconnection1.execute(sqlstr2);
      ...
      adoconnection1.execute(sqlstrN);
      adoconnection1.commitrans;       // 提交事务
      showmessage('操作成功');
    except
      adoconnection1.rollbacktrans;    // 事务回滚
      showmessage('操作失败');
    end;
      

  5.   

    谢谢楼上,这个方法我是知道的。我最近在考虑用rtc做应用服务器,也在应用服务器上肯定不能给每个客户端连接都建一个持久的connection的,要使用连接池的方式,这就意味着客户端执行多个 execsql 时,有可能每个执行用的不是同一个 connection,这个时候,就不知道事务怎么处理了!
      

  6.   

    一般情况下,c/s 方式,在客户端可以使用如下类似语句来管理事务:begintran;
    execsql(...);
    execsql(...);
    committran;但是,如果是连接应用服务器的情况(或者在利用多线程执行 execsql),因为没法确保每次 execsql 均使用同一个 connection ,这就造成了 begintran 没法用。所以就问这个问题,是不是多个 connection 没法使用同一个事务,只能想办法避免是吧?
      

  7.   

    连接池?
    咋不用FireDAC、DataSnap技术
      

  8.   

    多线程内是独立的会话连接,也可以并行执行或查询sql语句,就是不能用事务。
      

  9.   

    出个骚主意,sql你可以定位一个结构体,结构体内有标志位等,主线程内一直循环查询标志位从而实现假的并发,但是这样子就可以使用事务了,有点子线程池的味道。主线程内只干这事,其他业务交给子线程,子线程和主线程通过windows消息的wm_copydata传递数据,或者以事件通知的方式。
      

  10.   

    这样的啊,你把那个连接对象封一下,加一个是否执行成功属性,自己写一个exec方法,在执行sql之前都开户事务(这里开启事务、提交事务都可以单独写成方法),同是返回那个连接对象,及改变(是否执行成功属性)的值(现在假设失败为false);
      调用;
     con1:=exec(sql1);
     con2:=exec(sql2);
     con3:=exec(sql3);
     con4:=exec(sql4);
     b:=con1.flag and con2.flag and con3.flag and con4.flag;
    //以下可以写成通用方法,如数组,集合之类,统一处理。
    if b then 
    begin
      con1.commit;
      con2.commit;
      con3.commit;
      con4.commit;
    end
    else
    begin
      con1.rollback();
      con2.rollback();
      con3.rollback();
      con4.rollback();
    end;