全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:3889
推到 Plurk!
推到 Facebook!

多層分散式應用程式如何處理錯誤的疑問

答題得分者是:Mickey
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-08-27 01:49:23 IP:219.68.xxx.xxx 訂閱
A Technical View of Borland MIDAS
(Multi-tier Distributed Application Services)
http://info.borland.com/midas/papers/technical/#tdud
仔細研讀, 意思是不是 Delphi 可以做到多層分散式的功能

如文章內的圖 Figure 1: The architecture of a remote dataset.

ClientDataSet1 -> DataSetProvider1 - > Table1
ClientDataSet2 -> DataSetProvider2 - > Table2
ClientDataSet3 -> DataSetProvider3 - > Table3

意思是可以對 Table1 Table2 Table3 異動!

該圖有三個 DataSetProvider(DSP), 當全部的異動是正確的情況下, 當然沒有問題!
不過當 ClientDataSet(CDS) 第一個 CDS1 成功, CDS2 失敗時, 應如何處理?

用標準元件的情況下!

CDS1 執行成功後, 會執行 Reconcile, 這時 ChangeCount 會變為 0, Change Log 被清空!
CDS2 假如異動時發生錯誤!

好了! 使用者把 CDS2 的錯誤修正之後, 如何再次 ApplyUpdate?

CDS1 應該不會再傳送Delta 給 DSP1 異動了! 因為根本沒有 Delta (被清空了)

如果改寫 Delphi 機制, 先把 Delta 傳送給 DSP, 三個 DSP 成功後, 最後才執行
三個 CDS 的Reconcile 問題解決了?

我想問在沒有改寫元件的情況是如何處理多個 DSP 異動的處理錯誤情況!
Delphi 原始元件, 只要單一個 CDS 執行成功, 就會執行 Reconcile 及 AfterApplyUpdates
這剛好是我要的! 但也不是我要的!
因為我想在 AfterApplyUpdates 處理一些程式碼, 經過Reconcile, 這時可接收到 DSP 端的
PropogateChanges 的資料!

不過當 CDS2 異動失敗後, CSD1 再也不會異動實際的資料庫...
mustapha.wang
資深會員


發表:88
回覆:407
積分:274
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-10-02 14:35:42 IP:222.68.xxx.xxx 訂閱
我是这样做的:
var
vResult:Variant;
begin
vResult:=DCOMConnection.AppServer.SaveData(VarArrayOf[ADS1.Delta,ADS2.Delta,ADS3.Delta]);
CDS1.Reconcile[vResult[0]);
CDS1.MergChangeLog;
CDS2.Reconcile[vResult[0]);
CDS2.MergChangeLog;
CDS3.Reconcile[vResult[0]);
CDS3.MergChangeLog;

服务器的SaveData
function xxx.SaveData(ADeltas:Variant):Variant;
var
i:integer;
begin
Result:=VarArrayCreate([0,VarArrayHighBound(ADeltas,1)],varVariant);
for i:=0 to VarArrayHighBound(ADeltas,1) do
Result[i]:=DataSetProvider.ApplyUpdate(ADeltas[i],0);
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-10-02 16:28:42 IP:139.175.xxx.xxx 訂閱
謝謝您, 可是...
我想問的是如何處理多個 DSP 異動的處理錯誤情況!
不是把 Delta 重新封裝後再傳給單一個 DSP 來異動.
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-10-03 23:05:19 IP:123.193.xxx.xxx 訂閱
用"rollback" 找一下Help, 我想應該可以找到你要的東西...
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-10-03 23:22:16 IP:139.175.xxx.xxx 訂閱
如前文...
CDS1 執行成功後, 會執行 Reconcile, 這時 ChangeCount 會變為 0, Change Log 被清空!
CDS2 假如異動時發生錯誤!

ROLLBACK ? CDS2 異動時發生錯誤! 這時資料庫當然要執行 ROLLBACK! 我已經 ROLLBACK 了!

如果前文
好了! 使用者把 CDS2 的錯誤修正之後, 如何再次 ApplyUpdate?
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-10-04 14:34:39 IP:218.163.xxx.xxx 訂閱
你好:

要做到...分段 Commit...

小有名氣的資料庫...大概都有..."SAVEPOINT" 機制...

我沒實作過透過 DataSetProvider 前後端這樣...做複雜的 Transaction...都是包成 DB Stored Procedure 去做

所以...或許可以考慮 Run-time 依據 各個CDS.Delta...包裝成複雜 Transaction 的 SQL 指令...

呵呵...有點狀況外...參考參考.
編輯記錄
Mickey 重新編輯於 2007-10-04 14:50:03, 註解 無‧
Mickey 重新編輯於 2007-10-04 14:51:34, 註解 無‧
Mickey 重新編輯於 2007-10-04 14:59:23, 註解 無‧
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-10-04 22:01:29 IP:59.105.xxx.xxx 訂閱
針對 http://info.borland.com/midas/papers/technical/#tdud 所提供的方法, 有人實做出來嗎?
當 cds2 或 cds3 發生錯誤時, 如何處理?

請回應的大大注意一下, cds2 cds3 連接不同的 dsp2 dsp3!
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-01-10 11:37:45 IP:218.163.xxx.xxx 訂閱
你好:

一個想法, 如果直接呼叫 TCustomClientDataSet 的 DoApplyUpdates Function, 讓 cd1/cd2/cd3 ChangeLog 不被 ApplyUpdates Method 處理掉.

當然...如果沒有異常發生, ApplyUpdate Method 相關的程序( 如 Reconcile / MergeChangeLog ), 都自己處理.
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-01-11 12:05:31 IP:139.175.xxx.xxx 訂閱
這個方式可行, cds 接收到 dsp 傳來的 PropogateChanges 資料, 先不做 Reconcile,
等三個 cds 檢查正確後才 Reconcile, 三個都成功再通知 dsp 執行 commit;

Borland 的範例寫的太簡單了, 實做必須撰寫大量的程式碼! 這樣範例是用來騙人 :(
RootKit
資深會員


發表:16
回覆:357
積分:419
註冊:2008-01-02

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-01-11 12:19:19 IP:61.222.xxx.xxx 訂閱
我的作法(有點忘記了!)
是將 Server 的 Transaction 機制拉到 Client 來做。

好處是三層用二層的寫法。
缺點寫入週期太長。容易 Record Change by other User。
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-01-12 12:54:50 IP:139.175.xxx.xxx 訂閱
CDS1, CDS2, CD3 的 Reconcile, 三個 CDS 成功後, 才能一起做!
不是像範例程式! CDS1 成功後就執行 CDS1 的 Reconcile, 沒有這麼簡單!

我是把 CDS1 CDS2 CDS3 先打包為單一 Delta! 回傳時, 加入自訂的 Delta
用來控制錯誤的情況及 DSP 端的 PropogateChanges 的資料!

不知道 "Server 的 Transaction 機制拉到 Client 來做"
是否可以解決 CDS1 先執行 Reconcile 的問題!
煩請 RootKit 大大, 仔細回想您的做法.
RootKit
資深會員


發表:16
回覆:357
積分:419
註冊:2008-01-02

發送簡訊給我
#12 引用回覆 回覆 發表時間:2008-01-13 17:06:21 IP:61.222.xxx.xxx 訂閱
太久沒寫三層,五年多。

實際上 ClientDataset 對應的就是遠端的TQuery 角色(透過DataProvider)。
將 BeginTrans、RollBack、..包成Com方法。
ClientDataset 使用方法,也是使用自訂方法。
不是使用 CommandText。

當然Transation 機制就是三個成功後才寫入。
記得我那時做是很成功的。不過我現在回想不起來。
以現在功力來講當然是小巫見大巫,稍微臭屁一下!

正所謂條條大路通三層。

保重


===================引 用 VICSYS 文 章===================
CDS1, CDS2, CD3 的 Reconcile, 三個 CDS 成功後, 才能一起做!
不是像範例程式! CDS1 成功後就執行 CDS1 的 Reconcile, 沒有這麼簡單!

我是把 CDS1 CDS2 CDS3 先打包為單一 Delta! 回傳時, 加入自訂的 Delta
用來控制錯誤的情況及 DSP 端的 PropogateChanges 的資料!

不知道 "Server 的 Transaction 機制拉到 Client 來做"
是否可以解決 CDS1 先執行 Reconcile 的問題!
煩請 RootKit 大大, 仔細回想您的做法.
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#13 引用回覆 回覆 發表時間:2008-01-14 16:01:42 IP:139.175.xxx.xxx 訂閱
Transation 也是三個成功後才寫入!
這樣來看, CDS1 也不能先執行 Reconcile.

不過還是謝謝您!
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#14 引用回覆 回覆 發表時間:2008-01-29 17:30:22 IP:220.135.xxx.xxx 訂閱
如果你要異動的表格Table1 /Table2 /Table3 本身 具備Master/Detail 關係 那摸恭喜你 你可以用ClientDataSet 的Nested Table 來解決這個問題,(表身的資料可以包成表頭的一個欄位 帶回給server)
如果不是的話 那\麼你只有自行開新方法大致過程如下
把CDS1 /CDS2 /CDS3 的Delta 變成參數帶回給server
在server 在自行call Provider的applyupdate 成功後 把 三個table 的reconcile 資料包成 olevarinat 帶回 給client
client 在自行做reconcile 動作
------
唉~
VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#15 引用回覆 回覆 發表時間:2008-01-29 23:05:40 IP:59.104.xxx.xxx 訂閱
很不幸! 原問題並不是 Nested Table. (連接方式不是這樣)
一開始我也是用封裝 Delta 的方式來處理多個 dsp 異動! 這時必須撰寫大量的程式碼來處理.
想說 delphi 不是提出超厲害的資料庫應用技術? 會不會我想太多? 寫錯了?
後來

看到上述的範例程式! 哇! 這麼厲害... 用原始元件就可做到!
實際上根本沒這麼簡單 :(

各位大大的解決方式, 都是重新封裝 Delta, 自行控制 Delta 異動.
我想只能這樣做了...
Mickey
版主


發表:77
回覆:1882
積分:1390
註冊:2002-12-11

發送簡訊給我
#16 引用回覆 回覆 發表時間:2008-01-30 08:29:52 IP:218.163.xxx.xxx 訂閱
我用 SOAP Server ( DBExpres ) , 不過觀念方法 , 應該一樣吧...參考參考...

procedure StartTransaction(Connect: TSoapConnection = nil);
var LConnect:TSoapConnection;
begin
Screen.Cursor := crHourGlass;
try
if Connect = nil then LConnect := g_connect
else LConnect := connect;
if (LConnect<>nil) then begin
if not LConnect.Connected then LConnect.Open;
if (LConnect.GetSOAPServer<>nil) then
ISOAPApp(LConnect.GetSOAPServer).StartTransaction;
end;
finally
Screen.Cursor := crDefault;
end;
end;

// 使用 TClientDataset Protected Method "DoApplyUpdates"
type TTempCustomClientDataSet = class(TCustomClientDataSet);

procedure xxx();
var R1, R2, R3 :integer;
RR1, RR2, RR3: OleVariant;
begin
StartTransaction; // 對應呼叫 SOAP AP Server SQLConnection.StartTransaction Method (DBExpress)
try
// 不能讓 ChangeLog 被 ApplyUpdates Method Merge 掉, 故使用 Protected Method
if cd1.ChangeCount>0 then
with TTempCustomClientDataSet(cd1) do RR1 := DoApplyUpdates(Delta, -1, R1);
if cd2.ChangeCount>0 then
with TTempCustomClientDataSet(cd2) do RR2 := DoApplyUpdates(Delta, -1, R2);
if cd3.ChangeCount>0 then
with TTempCustomClientDataSet(cd3) do RR3 := DoApplyUpdates(Delta, -1, R3);

...// do something and raise exception when error

if VarIsNull(RR1) then cd1.MergeChangeLog;
if VarIsNull(RR2) then cd2.MergeChangeLog;
if VarIsNull(RR3) then cd3.MergeChangeLog;

Commit; // 對應呼叫 SOAP AP Server SQLConnection.Commit Method (DBExpress)
except
cd1.CancelUpdates;
cd2.CancelUpdates;
cd3.CancelUpdates;
Rollback; // 對應呼叫 SOAP AP Server SQLConnection.RollBack Method (DBExpress)
raise;
end;
end;

VICSYS
初階會員


發表:21
回覆:64
積分:32
註冊:2002-10-10

發送簡訊給我
#17 引用回覆 回覆 發表時間:2008-01-30 11:23:51 IP:59.105.xxx.xxx 訂閱
直接呼叫 DoApplyUpdates 的方式可以不用封裝 Delta!

如果 cds1 cds2 cds3 的changecount 都大於0, 當 cds3 發生 error 時!
首先, 先把 Mickey 大大程式碼, 去掉 except 內的 CancelUpdates!
因為不想清除 cds1, cds2 所做的變更! 使用者修正好 cds3 的 error, 可以再次 ApplyUpdates!

再來, 因為 cd3 發生錯誤, 所以 PR3 不為 NULL! 可以去執行 Reconcile(PR3), 得到錯誤的資訊!
(使用者修正好 cds3 的 error, 再次 ApplyUpdates)

這個方式可行!

我想這個問題, 可以結案了...
系統時間:2017-12-15 19:49:30
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!