我学习三层数据库开发时,为了解决数据提交冲突的问题,在工程中加入了Reconcile对话框,但它似乎不起作用,向各位请教。
  加入Reconcile对话框后处理ClientDataSet的OnReconcile事件,写上 Action := HandleReconcileError(DataSet, UpdateKind, E);然后测试,运行程序,修改一个数据,不提交。然后打开数据库,修改了同一条记录中的另一个数据,然后再回到程序进行提交,弹出了Reconcile对话框,但上面只有Skip、Cancel、Correct三个选项,选任何一个都无法把数据提交。于是我胡乱修改了Reconcile对话框的代码,去掉了FCurColIdx > 0的条件,让Refresh和Merge选项出现,但仍然无济于事。
  我的问题是,像我做试验的这种情况,一个用户修改了数据未提交,另一个用户也修改了数据但提交了,如何才能让第一个用户也把数据提交上去?或者不行的话,让第一个用户的数据立即变成最新的也行,现在我的情况下,不管用户在Reconcile对话框中选什么,他都处于一种很被动的地位,只能Revert操作再刷新数据才能继续工作。我对Reconcile对话框的作用是否有所误解,请为我解释一下Reconcile对话框的具体功能。
  谢谢!

解决方案 »

  1.   

    我说说,也许是你把这个更新纪录的匹配搞得太死了,很多时候记录的更新定位都没有必要匹配整个纪录的所有字段,换句话说,没有必要让中间层的Provider产生所有字段值匹配的where子句,除非要更新的表没有关键字段。比如,对于表T1(* field1, field2, field3)的纪录R1 ( 1, 2, 3 ); 
    用户A和用户B都读取到本地缓存,然后用户B对R1实施了修改,并提交到数据库。
    此时,假设R1变成 R1' ( 1, 2, 4);
    如果用户A准备应用一个这样的修改: R1''(1, 2, 5),那么产生的SQL大概是   update T1 set field3 = 5 where field1 = 1 and field2 = 2 and field3 = 3因为这一时刻的R1的field3实际上已经变成4了,所以匹配失败,语句的affected record count为0,这使得用户A所在的客户端触发了OnReconcile,也就出现了你所说的情形。
    通常表都设有关键字段,更新的时候只需匹配关键字段就可以了。在上面的例子,假设field1是T1的关键字,那么解决办法就是使得Provider产生   update T1 set field3 = 5 where field1 = 1的语句。你调整一下中间层的Provider的某个属性可以达到这个目的,具体的属性名称,我忘了,好像是UpdateFlags。在只匹配关键字段和不允许修改关键字段值的情况下,一个用户提交了对某个纪录的修改导致另一个用户提交对同一纪录的修改失败的情形就很少了。通常只会发生要修改的纪录已经不存在的异常(被删除了)。那么这时,修改纪录引起的异常通常是原始记录已被删除或更新违反了数据表的关系约束,因而,通知用户和期望用户协调就显得很自然了。
      

  2.   

    你还要汉化Reconcile吗?难道要用户学习调合数据吗?
    我认为业务逻辑的问题应该显式的表现给用户,而不要只是告诉用户某个值重复了之类的信息。