多层应用中的事务处理,是必须的,如果处理不好,就会出现各种数据不同步的现象,无法投入使用。以前用ASTA实现的多层应用,是在客户端利用ASTA机 制,将要提交的数据集、执行的SQL及SP,统统生成到一个脚本中,在ASTA是TAstaParamList,然后一次性提交到服务器,在服务器端在执 行这个脚本时,开启事务,执行脚本,如果成功则Commit,失败则Rollback。

kbmMW提供了更好的事务处理机制,即可以在服务器端做事务处理(TkbmMWTransactionResolve)也可以在客户端处理(TkbmMWClientTransactionResolve)。

在客户端,只要利用kbmMWClientTransactionResolve.Resolve(Query1,Query2,...)即可实现事务控制,此方法返回True,表明事务提交成功。如果提交失败,服务器端自动Rollback,完成事务回滚。

有几个事件可以捕获提交失败信息。

1.kbmMWClientQuery.OnResolveError事件

2.kbmMWClientTransactionResolve.onResolveError事件

此外,当kbmMWClientQuery在kbmMWClientTransactionResolve提时失败时,kbmMWClientTransactionResolve会为kbmMWClientQuery生成具体的错误记录的信息,保存在kbmMWClientQuery属性中,该属性是kbmMWMemTable类型。

利用这几种方式,可以很好的处理事务失败后的错误提示等进一步处理。

问题是当提交失账时,会产生新的问题:

1.假设有T1,T2两个物理表,需要用户同时修改并提交

2.当用户对T1,T2都做了修改后,用kbmMWClientTransactionResolve.Resolve(T1,T2)提交给服务器,当t2提交失败时,比如主键重复,问题就来了。

3.如果用户修改了T2的主键重复错误,再次提交,这时,不会再产生提交错误。

4.重新打开T1,T2,会发现T1的修改丢失,而T2正常修改了。

这种情况,对用户的操作过程来讲,是大问题,明明改了业务数据,保存时产生错误,按错误提示修正了错误数据,再保存,系统保存成功,再次调出这笔业务数据,用户会发现,修改结果没有被正确的保存!

对开发者来说,就是要在事务提交失败后,能恢复失败前的现场,即要把T1,T2的Delta保存起来,不能因为提交失败,而毁掉T1,T2的修改!

试图查找kbmMW提供现成的机制(其实,感觉不应该发生这样的问题),没有找到。于是想一个方法,就是Resolve前将T1,T2保存起来,提交有错误再恢复。

用AllData方法不行

代码:

在BeforeResolve事件保存

procedure TForm2.kbmMWClientTransactionResolver1BeforeResolve(Sender: TObject;
  const ADatasets: TkbmMWClientCursorArray);
begin
  v1:=kbmMWClientQuery1.AllData;
  v2:=kbmMWClientQuery2.AllData;

end;

//提交不成功,试图恢复(这里只是测试,正常应恢复没有出错的Query,好能再一次提交)

procedure TForm2.Button2Click(Sender: TObject);
begin
  if not kbmMWClientTransactionResolver1.Resolve([kbmMWClientQuery1,kbmMWClientQuery2,kbmMWClientQuery3]) then begin
    kbmMWClientQuery1.AllData:=v1;//这句出错,提示非法的属性值
    kbmMWClientQuery2.AllData:=v2;
  end;
end;

还有一种方法,就是把delta写入流,提交失败再恢复,不知是否可行?先放一下。

问题一定出在TkbmMWClientTransactionResolver.Resolve方法中,硬着头皮跟踪一下,咱这功力看大侠的套路,心惊胆颤,运气还不错,终于查到,问题出ProcessErrorTable方法中:

procedure TkbmMWCustomPooledCursor.ProcessErrorTable

在这个方法中,这里做了CheckPoint,把Delta干掉了!当提交的数据集没有返回ErrorTalbe时,系统认为这个数据集正确提交,所以做了CheckPoint。

// Check if no errortable defined.
     if (FErrorTable.FieldCount=0) or (FErrorTable.RecordCount<=0) then
     begin
          CheckPoint;
          exit;
     end;

原因找到了,一时间还想不出最好的修改方法来解决这个问题。试图找到一个属性来控制这种行为,也没有找到。等xalion来帮助了!

和xalion讨论该问题,也没有找到kbmMW已有的机制,对于上面提到的问题点,也可以确定。

再进一步分析一下ClientTransactionResolve.Resolve方法的执行过程,大体上分三步:

1.对提交的数据集,制作成Variant数组及Stream

2.将1生成的内容一次性提交到服务器端并接收返回的结果

3.利用返回结果对每一个提交的数据集进行ErrorTable处理,问题就出在这一步上。

首先,kbmMW从返回的结果,生成每个数据集的ErrorTable内容,然后根据ErrorTable,调用ProcessErrorTable方 法,ProcessErrorTable方法有两个主要目的:如果无错,则调用CheckPoint,取消这次提前的修改内容,有错,不调用 CheckPoint,触发OnResolveError事件。

对于一个数据集是否要Checkpoint,不应该取决于当前数据集是否有错,而应该由本次提要的结果来决定,就是说:当事务成功,则每一个数据集都应该做Checkpoint,事务不成功,则对于无错的数据集也不能Checkpoint!

按此想法,对ClientTransactionResolve.Resolve做了修改,测试上面遇到的问题,可以正确保存用户的修改。

修改方法是注册掉原ProcessErrorTable的调用,然后增加下面的代码,核心那行,我加黑了!

cnt:=0;
              for i:=low(ADatasets) to high(ADatasets) do
              begin
                   with ADatasets[i] do
                   begin
                        if not IsDataModified then continue;
                        v:=vResult[cnt];
                        inc(cnt);
                        if VarIsNull(v) then continue;
                        if VarArrayHighBound(v,1)>2 then
                           sFlags:=v[3]
                        else
                           sFlags:='';
                        NoCheckpointOnError:=(pos('NOCHECKPOINTONERROR',sFlags)>0);

DisableMasterDetail;
                        try
                           bm:=GetBookmark;
                           try
                              //如果整体事务成功或者当前表有错误
                              if Result or (ErrorTable.RecordCount>0) then
                                 ProcessErrorTable(TransactionOperation<>mwtoResolve,NoCheckpointOnError);

                           finally
                              try
                                 GotoBookmark(bm);
                              except
                              end;
                              FreeBookmark(bm);
                           end;
                        finally
                           EnableMasterDetail;
                        end;
                   end;
              end;

[转载红鱼儿]kbmmw 开发点滴:kbmMW客户端提交事务的现场处理相关推荐

  1. [转载红鱼儿]kbmmw 开发点滴:kbmMW 命名查询(Named Query)

    所谓命名查询(Named Query),指客户端的Query通过指定的名称,使用服务器端的Query操作(查.增.删.改)数据库.通过Named Query机制,实现事先在服务器端设置好SQL,达到在 ...

  2. [转载红鱼儿]kbmmw 开发点滴:kbmMW:Unknown property:indexes

    利用kbmMW的QueryServices,对数据集进行提交,当改用JSON格式时,客户端提交时,会产生这个错误,明明已经更新数据库,也产生这个错误!如果换成Bin格式,则正常. 能过查看kbmMWJ ...

  3. [转载红鱼儿]kbmmw 开发点滴:EarlyAuthentication

    kbmmw 开发点滴:EarlyAuthentication 1.kbmMWServer.EarlyAuthentication的作用: 当为真是,当客户端请求时,先触发kbmMWServer的OnA ...

  4. [转载红鱼儿]kbmmw 开发点滴:Authorization failed.

    开始利用kbmmw实作项目,第一件事就是为的服务端加用户的认证.如果客户端发来的请求无法在服务器端通过认证,即客户端认证失败,会在客户端弹出一个错误提示窗口:Authorization failed. ...

  5. [转载红鱼儿]kbmmw 开发点滴:TkbmMWLock用法

    TStringList不是线程安全的,当我们在线程用到他是,要做保护.方法有两种,一种是用delphi自带的Critical,另外一种就是kbmMW为我们提供的TkbmMWLock类. 现在我们看看如 ...

  6. [转载红鱼儿]kbmmw 开发点滴:ErrorTable用法

    TkbmMWClientQuery有一个ErrorTable属性,用于记录提交Query时返回的错误结果.当用户保存修改的业务数据,出错时,可以用ErrorTable定位出错的记录并提示错误信息. 下 ...

  7. [转载红鱼儿]kbmmw 开发点滴:kbmMWQuery插入记录

    想利用TkbmMWUNIDACQuery插入一条记录,结果遇到问题,显示: 不允许从数据类型 sql_variant 到 varchar 的隐式转换.请使用 CONVERT 函数来运行此查询.这是什么 ...

  8. kbmMW均衡负载与容灾(3)(转载红鱼儿)

    在kbmMW均衡负载与容灾(1)中,介绍了利用ClientTransport的OnReconnect事件,对联接的应用服务器的地址进行更换,做容灾处理.实际上,作者还给我们提供了另外一种机制,直接在C ...

  9. kbmMW均衡负载与容灾(2)(转载红鱼儿)

    集中式均衡负载 为实现集中式均衡负载方案,需要实现两个不同的应用服务器,一个是只包含均衡负载组件再无其他内容的应用服务器,可称之为均衡负载应用服务器,下文简称LB Server,另外一个就是包含一个或 ...

最新文章

  1. 查询所有张姓同学学号6_只需简单几步 做出属于老师自己的专属成绩查询表格 方便家长查询...
  2. office插件开发_Visual Studio Code有哪些你常用的插件?
  3. 找不到java.vbs_无法找到脚本*.VBS的脚本引擎解决办法
  4. 【数据结构与算法】之深入解析“串联所有单词的子串”的求解思路与算法示例
  5. 自定义的Android EditText
  6. 如何在FineUIMvc(ASP.NET MVC)中显示复杂的表格列数据(列表和对象)?
  7. 【华为云技术分享】一文掌握5种常用的机器学习模型及其优缺点
  8. 以后再别这样做,否则你的苹果华为将挂在墙上
  9. HyperX Savage系列 DDR3 2400 16GB (8GBx2)玩虚拟化部署
  10. 计算机专业实训是干什么,计算机系实习目的是什么
  11. OSPF篇——SPF算法——002
  12. 我还在努力,你千万不要喜欢上别人
  13. aseprite手机版_Voxel像素画体素模型转拼豆图纸方法
  14. 变频器的主电路 详解
  15. 微信特殊字符包括颜文字、表情的后台存储及前端展示方法
  16. python画地图柱状图_Python 如何画出漂亮的地图?
  17. 2022最新全网千图网素材解析网站工作原理,附带成品。
  18. C++打开文件夹中的多个文件并计算文件中数据的平均值
  19. 关于word页眉页脚的设置-页码不连续的问题
  20. aux ps 和top_关于vmstat,top,ps aux查看的cpu占用率不一致的问题

热门文章

  1. Linux中内存管理详解
  2. Java中gif动图缩略图处理
  3. C3P0连接池使用教程
  4. FindWindow用法
  5. 彻底删除mysql服务
  6. “基于云平台的移动终端实时渲染”学习参考
  7. 基于OMAP平台的声源定位系统设计与实现
  8. 东芝rc100装linux,东芝RC100的小伙伴们,快来检查下你的固件版本
  9. Java键盘输入一个数字, 输出其绝对值
  10. SQL 存储过程 调试