RO39 – 在一个事务中实现多个ClientDataSets 更新
来源:互联网 发布:秦时明月惊鲵是谁知乎 编辑:程序博客网 时间:2024/05/24 06:55
从两层迁移到三层第一个要面临的窍门就是摆脱在客户端控制事务.客户端不应该开始和提交事务.事实上客户端应该不知道任何事物.所有的事务逻辑应该放在服务端.
本文向你展示如何在RemObjects DataSnap服务中创建一个方法,用以传递一个ClientDataSet. Delta集合并在单独的事务中向数据库中更新,以便于在更新时发生异常时回滚事务.
这个方法只适用于你使用非嵌套(主从关系)的ClientDataSets 的情况,因为DataSnap默认情况下已经在单独事务中使用嵌套(主从关系)数据集.
你现在需要一个RO DataSnap server,由于我不打算介绍如何创建这种服务,所以我们使用一个已经存在的服务.
首先,你需要在服务端RODL中创建一下数据类型.使用RO Service Builder,创建一个包含ProviderName (string) 和 Delta (binary)成员的DeltaToApply结构体:
然后创建DeltaToApply类型的数组:
接下来,在服务端创建接收这个数组的函数.我将这个函数添加到包含所有Provider的同一个服务中,因为我们要使用这个Provider更新数据:
方法实现如下:
procedure TNewService.ApplyUpdates(var ADeltaArray: DeltaArray);
var
I: Integer;
Provider: TDataSetProvider;
ErrorCount: Integer;
begin
// Put your code to start transaction
try
for I := 0 to ADeltaArray.Count - 1 do
begin
Provider := FindProvider(ADeltaArray[I].ProviderName);
if not Assigned(Provider) then
raise Exception.Create('Provider not found: ' + ADeltaArray[I].ProviderName);
Provider.ApplyUpdates(VariantFromBinary(ADeltaArray[I].Delta), 0, ErrorCount);
if ErrorCount > 0 then
// Put your code to handle errors
raise Exception.Create('Errors during applyupdates: ' + Provider.Name);
end;
// Put your code to commit the transaction
except
// Put your code to rollback the transaction
raise;
end;
end;
我已经创建了一个帮助函数去根据名字获取一个Provider:
function TNewService.FindProvider(ProviderName: string): TDataSetProvider;
var
Component: TObject;
begin
Component := FindComponent(ProviderName);
if Component is TDataSetProvider then
Result := Component as TDataSetProvider
else
Result := nil;
end;
服务端完成.在客户端,你需要创建一个方法将所有的ClientDataSet.Delta保存在数组并将其发送到服务端:
procedure TClientForm.ApplyUpdates(ClientDataSets: array of TClientDataSet);
var
Deltas: DeltaArray;
Delta: DeltaToApply;
I: Integer;
begin
Deltas := DeltaArray.Create;
try
for I := Low(ClientDataSets) to High(ClientDataSets) do
begin
if ClientDataSets[I].ChangeCount = 0 then
Continue;
Delta := Deltas.Add;
Delta.ProviderName := ClientDataSets[I].ProviderName;
Delta.Delta := BinaryFromVariant(ClientDataSets[I].Delta);
end;
CoNewService.Create(ROMessage, ROChannel).ApplyUpdates(Deltas);
finally
Deltas.Free;
end;
end;
VariantFromBinary 和 BinaryFromVariant 方法在uROBinaryHelpers单元内.
最后,你只需要在客户端调用这个方法传递所有的你需要在同一个事务中更新的ClientDataSet:
ApplyUpdates([ClientDataSet1, ClientDataSet2, ClientDataSet3]);
好了!我希望这能对你有帮助.如果你发现代码存在问题或有可以改进的地方请尽快通知我以便于修正.
- RO39 – 在一个事务中实现多个ClientDataSets 更新
- RO39 – 在一个事务中实现多个ClientDataSets 更新
- RO39 – 在一个事务中实现多个ClientDataSets 更新
- RO39 – 在一个事务中实现多个ClientDataSets 更新
- RemObject 在一个事务中实现多个clientdataset的更新
- 如何在一个事务中插入一对多关系的多个EO对象?
- 在一个FORM中如何实现多个ACTION动作
- SQL中运用事务实现多表更新操作
- 在WCF中实现事务
- 在ABAP中制作一个多屏幕的应用事务
- 在一个事务里有多条更新如何从Undo查找前镜像
- 在数据库中开始一个事务。
- 在数据库中开始一个事务
- 如何在一个FPGA中实现多个UART接口模块?[
- 第二章(契约 在一个服务中实现多个契约和终结点)
- 多个form表单之间的数据在一个方法中实现,利用入口思想
- 在一个form表单中根据不同按钮实现多个action事件
- JCO3调用SAP多个API时,需注意事务控制在一个session内
- 图片缓存SD卡,使用LRU算法管理图片
- UniDAC使用SQLite数据库可能碰到的问题 .
- 回顾编程十年
- Windows完成端口与Linux epoll技术简介
- Chapter04-获取主机版本系统和验证系统是否是Vista
- RO39 – 在一个事务中实现多个ClientDataSets 更新
- NSArray
- Fedora下SVN环境搭建
- DLL文件简介和处理
- Delphi中多线程下使用使用 UniDAC+MSSQL 需要注意的问题 .
- uniDAC和ado params的区别 .
- Intents and Intent Filters
- UniDAC 的 RecordCount 属性注意事项 .
- x264输出文件的后缀名可设为哪些?详细报告