同access,那個Access數據庫好像有防止更改沖突的機制,但是我們“微小”的微軟XMLDom沒有給我們准備這個防止沖突!
具體例子:
兩人同時調用寫入XML文件的ASP,結果只有一個人能寫進去,另外一個卻沒有。
這跟XMLDom的工作方法有關。
用XMLDom.load(Path)載入文件之後,文本對象被載入內存,只讀屬性解除。當兩個人同時載入一個XML文件時,XMLDom的內容是一樣的。這樣問題來了。
例如:
tmp1.XML
<Root></Root>
A君在XMLDom根中插入一個子標簽<Chd1>Chd1</Chd1>,B君在XMLDom中又插入一個子標簽<Chd2>Chd2</Chd2>。然後兩個人保存,現在我們來看兩人的XMLDom對象都是什麼東西
A:
<Root>
<Chd1>Chd1</Chd1>
</Root>
B:
<Root>
<Chd2>Chd2</Chd2>
</Root>
OK,誰處理的慢,誰就被寫進tmp1.XML文件啦。
但是我們想得到的是,兩個人增加的東西都寫入到XML文件,就是tmp1.XML的結果應該是這樣的。
tmp1.XML
<Root>
<Chd1>Chd1</Chd1>
<Chd2>Chd2</Chd2>
</Root>
如何解決這個問題呢?
初步構想:
方法1:
利用Application.Lock的特性:在載入XML文件之前,建立一個Application,並且Lock起來,在寫入完成之後再Unload。那麼,同時執行的ASP就會停在Application.Lock那裡,等Application重新開放再執行下來,從而達到XML異步寫入的目的。具體例子:
tmp1.ASP
以下內容為程序代碼:<%
application("XMLFiles1"),Lock
XMLDom.loat(path)
處理過程
XMLDom.save(path)
application("XMLFiles1").unlock
%>
這個好是好,但是有個缺點,如果有10個XML文件就要建立10個application,有10000個就要建立10000個application,天。
方法2:
還是利用application,不過這次不同以前:這次只用到一個application,把各個操作請求編號起來,建立一個隊列,再把操作請求的編號返回诶客戶端。服務器每執行完一個操作就刪一個編號,那麼隊列就一點一點的向前了。客戶端根據自己的隊列編號,定期刷新一下,要求服務器執行自己的操作。這個代碼太復雜了,基本是這樣的流程
服務器建立Application -> tmp2.asp用來添加操作編號 -> 返回當前操作的編號給客戶端 -> 客戶端定期刷新並提交自己的操作編號給tmp3.asp -> tmp3.asp用來做操作XML -> tmp3.asp判斷是否輪到該編號,輪到就做,未輪到返回錯誤信息 -> tmp3.ASP做了之後隊列前移,刪除操作編號
這個方法僅僅占用一個Application(可以對編號進行規則編制,例如[tmp1.XML|1|2|3}[tmp2.XML|1|2|3],其中第一個是XML文件名,後面那些是操作編號,|是間隔符,[]是分割每個文件的標識),但是客戶端刷新時間不好定,太小了就占服務器資源太多,太久了隊列移動就十分緩慢。
方法3:
為每個操作建立一個暫時的XML文件,由服務器在一定時間內歸總一次:這個方法對於對時間性需求不大的還可以,可是,對於時間性要求非常高的就不行了。例如論壇。(其實時間性要求不大的話完全不必要顧慮沖突這個問題)