您的位置:首页 > 其它

RO39 – 在一个事务中实现多个ClientDataSets 更新

2014-05-07 20:45 465 查看
RO39 – 在一个事务中实现多个ClientDataSets 更新



作者 Erick Sasse (葡萄牙语版本 www.ericksasse.com.br)

RemObjects提示:我们相信本文是正确的,但我们不做任何保证.在此感谢Erick
Sasse写的文章,很高兴在此发表.

从两层迁移到三层第一个要面临的窍门就是摆脱在客户端控制事务.客户端不应该开始和提交事务.事实上客户端应该不知道任何事物.所有的事务逻辑应该放在服务端.

本文向你展示如何在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]);

好了!我希望这能对你有帮助.如果你发现代码存在问题或有可以改进的地方请尽快通知我以便于修正.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐