最近一直在考虑多客户端并发访问数据库的问题,我的想法是多客户端同一时间分别读取互相有交集的数据集并对数据集中的数据进行修改,如果一个客户端修改了一条记录那么在其他客户端的数据集中相应的这条记录自动刷新到最新的数据。
    我查了一些资料,cursor type为ctKeyset、ctDynamic的服务器端游标能看到其他客户端对数据的修改,在游标滚动的时候当前记录会自动刷新到最新的数据。由于ctDynamic不支持books,我要用dbgrid做前端显示所以采用了ctKeyset。但是我发现用dbEdit这类显示单条数据控件的时候滚动游标能够刷新到其他客户端修改的最新数据但是用dbgrid这种同时显示多条记录的控件在滚动游标的时候数据没有刷新,哪位仁兄知道这是什么原因?
    另外,关于游标哪位能对比ctdynamic解释一下ctKeyset的底层原理。我发现使用ctStatic和ctDynamic型游标的时候,如果两个客户端同时读取了一条记录,其中一个客户端先修改了这条记录,而另一个客户端在没有刷新数据集的情况下尝试修改这条记录会报错:“无法为更新定位行,一些值可能已在最后一次读取后已更改”,这样避免了一些不知情的更新数据覆盖。但是,当使用ctKeyset型游标的时候却没有这种机制,第二个客户端对记录已经发生变化不知情的情况下依然允许修改记录,为什么会有这样的区别呢?
    哪位有更好的方法欢迎赐教,但是效率一定要高于requery。

解决方案 »

  1.   

    我的做法是不需要知道别人有没有修改,以最后更新的为准
    如果是用TClientDataSet自带的appapplyupdata方法,则把服务器的providerflages的pfinKey设为真就可以了
      

  2.   

    用ClientDataSet配合Socket。每个记录有一个版本号,有个整数全局变量,每发生一次更改让变量加1,并把数字放到记录的版本号字段中。数据更新后,把服务器端版本号写入客户段全局变量中,定期查询高于版本号的更改记录,查到后,将记录更新到ClientDataSet中,并调用MergeChangeLog。
      

  3.   

    to kongfancheng,这个方法似乎可行,但是定期查询的话,如果客户端比较多不知道对网络和数据库的压力怎么样
      

  4.   

    to StreamOne(梦醒):确实存在这个问题。所以,Timer不可设定的太小,20客户端可设定2秒查询一次。当然,如果用InterBase或者Oralce的话,可以用Event。
      

  5.   

    如果你用的SQL SERVER2000就不用考虑这个问题了,数据库本身有这个功能
      

  6.   

    to baronyang(魔蝎(交流QQ195428528)) ,请看完整帖子再回帖。