事务处理只在你需要提交时才使用,当你打开数据集,在编辑时不需锁定,这样其他用户就可以同时使用.举个例子:
...
procedure edit;
begin
  adoquery1.open;
  adoquery1.edit;
end;
procedure save;
begin
  adoconnection.beginstran;
  try
    adoquery1.applyupdates;
    adoconnection.commition;
  except
    adoconnection.rollback;
  end;
end;
不要一进入窗体便
adoconnection.beginstran;

解决方案 »

  1.   

    要看你是用那个 SQL server了, 一些SQL server可以不用Table lock 或 Page
    lock 或 record lock, 都可以让多人同时更新的.
    例如Interbase有Tranactional versioning (事务版本) 机制, 即是每事务
    都有自己独立的序号, 数据库是记着最新的序号, 就算两人同时更新, 该序号都
    是不同的, 都某人先更新数据了, 当前的数据库上的序号便更新了. 之後, 迟了的那个用户, 当要update数据时便会发觉他的序号已迟了, 而报错.  因些这个序
    号便隔离了多用所更新的数据但不用预先把数据上锁.所以当用於多人同时更新的数据时, 便应少用 cache update, 最好每次只下载或
    上载单一个纪录便最保险了.
      

  2.   

    谢谢楼上各位, procedure save;
    begin
      adoconnection.beginstran;
      try
        adoquery1.applyupdates;  //这条语句有什么作用,以前我没用过,是不是先更新一下adoquery1里的内容
        adoconnection.commition;
      except
        adoconnection.rollback;
      end;
    end;好像没这么简单吧, 这些概念我还没太理解
      

  3.   

    adoquery1.applyupdates; 是批量更新,由于采用缓冲机制的缘故,将数据的更新放在了可户端但要求用异常保护,防止客户修改所造成的错误,所以又用到了rollback.
      

  4.   

    如果你是为了修改才读的数据,就要这样写:
    select ...for update;
    这样,在这个事务没有结束之前,其它有“for update”的select语句就会等待。
    注意:一定要起用事务。
      

  5.   

    当A用户正在编辑10号记录,而B用户点击删除10号记录,(提示B用户本记录正处于编辑状态不能被删队‘)这是怎样做的。
      

  6.   

    为了把问题描述得更详细一些, 我做了一个测试,放一个adoquery (select * from table1); 三个字段.
    adoquery-->连接到adoconnection,
    datasource连接 adoquery1,放一个dbgrid,控件,再放一个增加,一个修改 ,一个删除按钮.dbgrid的datasorce连接到datasource1, 我在form1的create事件里 with adoquery1 do
    begin
      active:=false;
      sql.clear;
      sql.add('select * from table1');
      active:=True;
    end;显示正常,1。点击添加操作; procedure Tform1.button1click(sender:object); //添加;
    begin
      Form2:=Tform2.create(application);
      Form2.option:=0;  //表示添加;
      adoquery1.append;
      Form2.showmodal;
    end; procedure Tform1.button1click(sender:object); //添加;
    begin
      Form2:=Tform2.create(application);
      Form2.option:=1;  //表示修改;
      adoquery1.edit;
      Form2.showmodal;
    end;
    进入Form2后,(我在form2放了两个 dbedit用于显示数据.编辑数据);另外还有一个确定按钮, 一个取消按钮.Public
    option:integer;Procedure Tform2.button1click(sender:object); 确定
    begin
       Try
       Adoconnection.Beginstran;
       ADOQUERY1.POST;
       Adoconnection.commit;
       except                   
       showmessage('删除不成功');   1.//这里的数据库错误类型是怎样确定的。
       Adoconnection.rollback;
       end;
    end;问题:
    不知道我上面写的是否合理,请大家指教。 我在单用户环境操作是没有问题的。
    但当两个用户(我故意这么测试, A用户点击该模块的Form1增加按钮, B用户也点击该模块的增加按钮, 这样当其中一个用户A先点击Form2“确定”
    保存成功,
    但是当B用户点击“确定”按钮时, A用户其实已经修改了数据,B用户此时操作将不成功, 事务回滚。
    ?这个事务回滚的原因是什么。语句怎样写。大家是怎样控制的。
      

  7.   

    楼上的都带星哦,为什么只问不答呢?
    其实在提交事务时如果出错?ADOConnection是会返回错误的.怎么返回你们查手册吧.
      

  8.   

    问题2,我用sql语句查询(结果来自三四个表),
    考虑在多用户环境下操作,我把结果存放在临时表(其实可以不用临时表,直接用adoquery.sql('select ..') active:=True,就可以把结果显示在dbgrid里面,但我为了让dbgrid里面能显示100条记录, 如果查询结果没有100条则添加 100-adoquery1.recordcoutn条空记录在后面)。  这样查询的结果保证dbgrid会显示100条记录, 用临时表对服务器有什么影响,客户多的情况下,会不会现并发情况,(我昨天看一篇贴子说本地临时表都是独立创建的。并不受影响)所以我才用了临时表。 不知是否合理。 
      

  9.   

    1、问题:在实际应用程序里,尽量不要用select * from table1这样的语句,而是要根据用户的条件写成select * from table1 where ...这样的语句。因为一般用户只允许修改自己输入的记录,不同用户的记录是不同的,这样加条件能很好的防止两个用户同时操作一条记录。
    2、同意menliwxj(有缘)的建议,事务处理只在你需要提交时才使用,当你打开数据集,在编辑时不需锁定,这样其他用户就可以同时使用.
    3、对sql server来说,如果没有改变设置,“当两个用户同时修改一条记录”这种情况实际是有先后的,前一个事务会给记录加更新锁,后一个事务只能等待前一个事务完成才能操作这条记录。而“一个用户修改一条记录而另一个用户确删掉了这条记录。” 也是有先后的,如果修改再前,修改加更新锁,完成修改后才能删除;如果删除再前,那修改的进程会找不到修改的记录而报错。  
     
      

  10.   

    何必用临时表呢?你要保证每次显示100条记录是吧,不够的话append呀,当然可能会涉及到主键的问题,你可以临时取一些主键值,或设主键为自增长型,当你在更新回数据库时删除掉那些没有改变的空记录即可.
      

  11.   

    to  Yang_(扬帆破浪)
    Procedure Tform2.button1click(sender:object); 确定
    begin
       Try
       Adoconnection.Beginstran;
       ADOQUERY1.POST;
       Adoconnection.commit;
       except                   
       showmessage('删除不成功');   1.//这里的数据库错误类型是怎样确定的。
       Adoconnection.rollback;
       end;
    end;我这样测试
    在提交的时候才锁定记录,  所以每个用户都可以编辑。
    当A用户在编辑10号记录时, 还未提交 正在进行中, B用户此时打开10号记录也进行编辑, 此时A按了保存按钮,执行了上面这段代码,保存成功, 而B用户也可以操作这条记录,这是属于行锁吗?点保存按钮时确出错了。键值未定义。是不是你讲的"前一个事务会给记录加更新锁,后一个事务只能等待前一个事务完成才能操作这条记录"这种情况.
      

  12.   

    to  Fzgta(蝈蝈) 我在程序里全部是adoquery,没有用adotable. 我不想用表锁,这样在多用户情况下,独占的情况是不是会好一些。当多用户同时增加一记录时,我想这样控制, 不知道思路有没有错。在form2里设一全局变量option,如果为0表示增加,为1表示编辑。当A用户在增加,B用户在增加, 此时两个人用的ID都是一样的。此时B用户提交了记录, 保存成功, (这我测试过了), 当A用户点保存时,出错,键值未定义。因为B用户刚刚添加了这个主键。存在重复关键字。 我就提示用户,该主键已经存在,自动修改主键取出表里ID最大值加1 作为A用户本次提交的ID.我用的是DBEDit, 好像这个DBedit 一打开,就把记录行锁定了。
      

  13.   

    新建一个表A 保存当前正在编辑的记录关键字及用户名
    当用户要编辑记录时 先检查刚才那个表A 如果有此记录则显示  'XXX正在修改'
    如果没有人在修改则添加此用户及表的关键字 
    我一开始是这么想的。 那这样就属于表锁定了。范围太大了。
    如果有30个用户在修改表, 大家都得等,不是很好。 对不对?