分布式旅行預(yù)訂系統(tǒng)_第1頁(yè)
已閱讀1頁(yè),還剩4頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p><b>  分布式旅行預(yù)訂系統(tǒng)</b></p><p><b>  ??必備知識(shí)</b></p><p>  具備數(shù)據(jù)庫(kù)系統(tǒng)原理或與之相當(dāng)?shù)闹R(shí)是完成本課程作業(yè)的前提。假定每一個(gè)學(xué)生都已經(jīng)了解了數(shù)據(jù)庫(kù)系統(tǒng)的基本實(shí)現(xiàn)技術(shù),包括對(duì)事務(wù)功能性的一個(gè)基本了解(例如,ACID性質(zhì))。</p><p>  此項(xiàng)課程作

2、業(yè),建議每個(gè)學(xué)生都具備一些用JAVA語(yǔ)言編程的經(jīng)驗(yàn),并且對(duì)并發(fā)程序的抽象概念,比如線程、互斥很熟悉。此項(xiàng)作業(yè)要求學(xué)生具備JAVA線程編程(JAVA THREADS)和JAVA 遠(yuǎn)程方法調(diào)用(JAVA RMI)的知識(shí),但并不要求對(duì)JAVA語(yǔ)言的其他方面,比如圖形用戶界面工具箱(GUI TOOLKITS)、基于JAVA的數(shù)據(jù)庫(kù)互連(JDBC)、服務(wù)器端嵌入程序(SEVLETS)及網(wǎng)頁(yè)內(nèi)嵌小程序(APPLETS)等知識(shí)很了解。</p&g

3、t;<p><b>  ?課程作業(yè)簡(jiǎn)介</b></p><p>  作業(yè)是由幾個(gè)步驟組織起來(lái)的,這些步驟遞歸地增加程序的成分和系統(tǒng)結(jié)構(gòu)。我們給每個(gè)成分都提供了通用的接口,此外,我們還提供了一個(gè)基本的檢測(cè)代碼用來(lái)檢測(cè)基本的功能。我們還將提供若干基本的已建好的模塊,比如鎖管理器(LOCK MANAGER)。</p><p>  實(shí)驗(yàn)評(píng)分將大體根據(jù)學(xué)生提交的自

4、動(dòng)進(jìn)行的測(cè)試程序,一個(gè)演示程序以及一個(gè)具體的設(shè)計(jì)文檔來(lái)評(píng)定。</p><p><b>  ?任務(wù)描述</b></p><p>  這個(gè)任務(wù)的目標(biāo)是用JAVA建立一個(gè)分布式的應(yīng)用程序以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的旅行預(yù)訂系統(tǒng)。為了完成此任務(wù),你將要經(jīng)歷三個(gè)階段:</p><p>  階段一 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的資源管理器(Resource Manager,一個(gè)具有

5、固定的表和操作集的非常簡(jiǎn)易的數(shù)據(jù)庫(kù)系統(tǒng)),用來(lái)支持并發(fā)事務(wù)的ACID性質(zhì)(原子性、一致性、獨(dú)立性、持久性);</p><p>  階段二 實(shí)現(xiàn)一個(gè)工作流程控制器(Workflow Controller)和一個(gè)事務(wù)管理器(Transaction Manager),用來(lái)在多個(gè)資源管理器(Resource Managers)之間實(shí)現(xiàn)分布式事務(wù)處理;</p><p>  ??簡(jiǎn)易的旅行資源管理器

6、(Simple Travel Resource Manager)</p><p>  實(shí)現(xiàn)一個(gè)簡(jiǎn)單的資源管理器(Resource Manager or RM),用來(lái)支持并發(fā)事務(wù)的ACID性質(zhì)(原子性、一致性、獨(dú)立性、持久性)。具體的說(shuō),這個(gè)RM存儲(chǔ)著關(guān)于航班,出租車,賓館房間和客戶的數(shù)據(jù)信息。多個(gè)客戶端通過(guò)一個(gè)事務(wù)處理界面可同時(shí)訪問(wèn)這個(gè)RM以查詢和更新數(shù)據(jù)。這個(gè)RM要保證這些并發(fā)事務(wù)的執(zhí)行正確性,即符合ACID性

7、質(zhì)的要求。</p><p>  從概念上講,這個(gè)RM存儲(chǔ)著下列表:</p><p>  FLIGHTS (String flightNum, int price, int numSeats, int numAvail)HOTELS(String location, int price, int numRooms, int numAvail)CARS(String location, i

8、nt price, int numCars, int numAvail)CUSTOMERS(String custName)RESERVATIONS(String custName, int resvType, String resvKey) </p><p>  為簡(jiǎn)單起見(jiàn),作下列假設(shè):</p><p>  假定這里只有一條航線,并且在給定的一個(gè)班機(jī)上,所有的座位價(jià)格也一樣;flig

9、htNum是表FLIGHTS的一個(gè)主鍵(primary key)。</p><p>  假定在同一個(gè)地方的所有的賓館房間價(jià)格也一樣;location是表HOTELS的一個(gè)主鍵。</p><p>  假定在同一個(gè)地方的所有的出租車價(jià)格也一樣;location是表 CARS的一個(gè)主鍵。</p><p>  custName是表CUSTOMERS的一個(gè)主鍵。</p&

10、gt;<p>  表RESERVATIONS包含那些和客戶預(yù)訂的航班、出租車或賓館房間相應(yīng)的條目,具體的說(shuō),resvType指預(yù)訂的類型(1為預(yù)訂航班,2為預(yù)訂賓館房間,3為預(yù)訂出租車),而resvKey是表RESERVATIONS的一個(gè)主鍵。</p><p>  在表FLIGHTS中,numAvail表示指定航班上未被預(yù)訂的座位數(shù)。對(duì)于一個(gè)給定的航班(flightNum),數(shù)據(jù)庫(kù)一致性的條件之一是

11、,表RESERVATIONS中所有預(yù)訂該航班的條目數(shù)加上該航班的剩余座位數(shù)必須等于該航班上總的座位數(shù)。這個(gè)條件對(duì)于表CARS和表HOTELS同樣適用。</p><p>  資源管理器(Resource Manager)的標(biāo)準(zhǔn)接口(詳見(jiàn)ResourceManager API)。這個(gè)接口允許每一個(gè)在RM中存儲(chǔ)的表中的行被添加、刪除和修改。你的工作是為每一個(gè)我們提供的接口寫(xiě)出實(shí)現(xiàn)程序。</p><p

12、>  RM支持事務(wù)處理。一個(gè)事務(wù)調(diào)用RM的start( )方法來(lái)獲取一個(gè)唯一的事務(wù)標(biāo)識(shí)(transaction id)。所有對(duì)RM的后續(xù)調(diào)用都要包括這個(gè)事務(wù)標(biāo)識(shí)。最后,事務(wù)調(diào)用commit( )或abort( )方法結(jié)束事務(wù)處理。一個(gè)典型的客戶端事務(wù)可能象以下這樣:(當(dāng)然,在現(xiàn)實(shí)中,你要檢查返回值及獲取異常。你也可以查看Client.java文件來(lái)看另一個(gè)例子)</p><p>  int xid = rm

13、.start ();</p><p>  // If it's cheap enough and there're seats left</p><p>  if (rm.queryFlightPrice(xid, "347") < 300 &&</p><p>  rm.queryFlight (xid,

14、"347") > 0) {</p><p>  rm.reserveFlight (xid, "John", "347");</p><p><b>  }</b></p><p>  rm.commit (xid); </p><p>  并發(fā)控制是通

15、過(guò)兩階段鎖(two-phase locking)來(lái)實(shí)現(xiàn)的。當(dāng)一個(gè)客戶端要求查詢或更新信息時(shí),你的RM要適當(dāng)?shù)亟o相應(yīng)元組加鎖,并在事務(wù)正常完成(commits)或異常中斷(abort)時(shí)釋放所有的鎖。我們提供了一個(gè)鎖管理器(lock manager)幫助你完成任務(wù)。這個(gè)鎖管理器支持以下API(這里給出的是偽代碼,實(shí)際的代碼請(qǐng)見(jiàn)LockManager API):</p><p>  lock(xid, thingBe

16、ingLocked, read|write) throws DeadlockException </p><p>  unlockAll(xid) </p><p>  如前所述,xid是唯一的事務(wù)標(biāo)識(shí)。鎖管理器用超時(shí)機(jī)制(目前設(shè)為10秒)來(lái)處理死鎖。一個(gè)死鎖操作會(huì)拋出一個(gè)死鎖異常(DeadlockException)。鎖管理器還用來(lái)處理鎖的轉(zhuǎn)換(也被稱為鎖的升級(jí))。鎖的升級(jí)發(fā)生在一個(gè)已具

17、備在某個(gè)元組上的‘讀鎖’的事務(wù)需要獲得此元組的‘寫(xiě)鎖’的時(shí)候。</p><p>  lock (xid, foo, read); // read foolock (xid, foo, write); // write foo</p><p>  其他的事務(wù)也可能具有foo上的‘讀鎖’,因此,在鎖升級(jí)時(shí)死鎖有可能發(fā)生。</p><p>  下面介紹如何開(kāi)始你的編程工

18、作:</p><p>  首先介紹一下對(duì)JAVA編程環(huán)境要求:</p><p>  你要安裝Jdk1.2.2以上版本,然后如下設(shè)置環(huán)境變量(假設(shè)你的JDK安裝目錄為C:\Program Files\j2sdk1.4.0_01,且你的項(xiàng)目文件所在的目錄是D:\project\):</p><p>  Set path = ……………; C:\Program Files

19、\j2sdk1.4.0_01\bin\</p><p>  Set classpath= .; C:\Program Files\j2sdk1.4.0_01\lib\tools.jar;C:\Program Files\j2sdk1.4.0_01\lib\dt.jar;C:\Program Files\j2sdk1.4.0_01\jre\lib\rt.jar;D:\project\</p><

20、;p>  提供的源碼(詳見(jiàn)API)有兩個(gè)壓縮包:lockmgr和transaction。其中,lockmgr實(shí)現(xiàn)了LockManager的功能,你不必修改這個(gè)包中的內(nèi)容。transaction提供了一些基本的類以幫助你完成工作,它包含了ResourceManager的接口。請(qǐng)注意,你不要修改此文件,你的RM實(shí)現(xiàn)要基于名為ResourceManagerImpl的類(以及一些自己定義的新類),這個(gè)類提供了ResourceManager

21、的接口。你必須自己編寫(xiě)接口實(shí)現(xiàn)代碼,以替代目前提供的這個(gè)ResourceManagerImpl.java文件中的接口實(shí)現(xiàn)代碼。</p><p>  事務(wù)目錄還包含一個(gè)簡(jiǎn)易的客戶端(詳見(jiàn)Client.java)。在實(shí)現(xiàn)中你可能想編寫(xiě)一些更復(fù)雜的客戶端來(lái)測(cè)試你的RM,但是課程不要求你提交自己編寫(xiě)的客戶端。</p><p>  客戶端通過(guò)JAVA 遠(yuǎn)程方法調(diào)用(JAVA Remote Metho

22、d Invocation or RMI)與RM進(jìn)行通信。你可以在http://java.sun.com/docs/books/tutorial/rmi/上看到RMI的使用指南。但是,這里給出的簡(jiǎn)易R(shí)esourceManagerImpl.java和Client.java已經(jīng)提供了這一部分所需要的所有RMI代碼。你唯一要做的是修改transaction/Makefile的第一行,以便給自己一個(gè)唯一的在RMI上注冊(cè)的端口號(hào),這樣你就不會(huì)與那些

23、和你碰巧使用同一臺(tái)機(jī)器的人在端口號(hào)上發(fā)生沖突了(請(qǐng)見(jiàn)后)。</p><p>  你要上交所有你編寫(xiě)的源代碼文件以及一個(gè)小的README文件(說(shuō)明文件)。</p><p><b>  編程提示:</b></p><p>  下面給出一個(gè)實(shí)現(xiàn)各個(gè)功能的方法步驟(請(qǐng)注意,以下各步驟并不是同一個(gè)難度的,某些步驟會(huì)比其他的步驟都難以實(shí)現(xiàn)):</p&

24、gt;<p>  ?步驟一: 實(shí)現(xiàn)一個(gè)簡(jiǎn)易的RM</p><p>  先忽略事務(wù)的原子性和持久性,另外假設(shè)數(shù)據(jù)都存儲(chǔ)在內(nèi)存中。一種可行的實(shí)現(xiàn)方法是把數(shù)據(jù)都存儲(chǔ)在一個(gè)或多個(gè)哈希表(hash tables)中。你可以為每一個(gè)數(shù)據(jù)庫(kù)表建立一個(gè)哈希表,或者把所有的數(shù)據(jù)庫(kù)表連接起來(lái)組成一個(gè)哈希表。這樣,數(shù)據(jù)庫(kù)表中的每一行都可作為哈希表的一個(gè)條目,并以數(shù)據(jù)庫(kù)的主鍵為索引。你也可以用一個(gè)JAVA的類來(lái)代表每一類型

25、的行,例如,用一個(gè)與FLIGHT數(shù)據(jù)庫(kù)表相應(yīng)的類,那么這個(gè)類就要含有flightNum, price, numSeats, numAvail等成員變量和一些其他數(shù)據(jù)以實(shí)現(xiàn)事務(wù)的ACID性質(zhì)。</p><p>  表RESERVATIONS并沒(méi)有主鍵,但是經(jīng)常以custName為索引;所以,一種可行的實(shí)現(xiàn)方法是把表RESERVATIONS和表CUSTOMERS聯(lián)合起來(lái)。這樣,就擁有了一個(gè)以custName為索引的哈

26、希表,并且每個(gè)條目都增加了resvType和resvKey兩個(gè)數(shù)據(jù)項(xiàng)。</p><p>  請(qǐng)注意,在這個(gè)簡(jiǎn)單的數(shù)據(jù)模型中,你只能讓同一個(gè)地方的價(jià)格保持一樣,因此,以下操作的實(shí)際結(jié)果為:</p><p>  addCars(T1, "San Diego", 4, $52);</p><p>  addCars(T2, "San Dieg

27、o", 7, $54);</p><p>  11輛出租車的價(jià)格都是54美元,而并不是其中的7輛車54美元,另外的4輛52美元!</p><p>  ?步驟二: 實(shí)現(xiàn)原子性(Atomicity)</p><p>  利用影子方法(shadowing)來(lái)實(shí)現(xiàn)事務(wù)的原子性。在內(nèi)存中保留兩個(gè)數(shù)據(jù)庫(kù)的拷貝,并且建立一個(gè)指針指向那個(gè)活躍的拷貝。把正在執(zhí)行的事務(wù)的各個(gè)

28、更新結(jié)果保留在一個(gè)獨(dú)立的哈希表中。當(dāng)這個(gè)事務(wù)正確完成時(shí),將事務(wù)的更新結(jié)果與那個(gè)不活躍的數(shù)據(jù)庫(kù)拷貝合并,然后交換指向活躍數(shù)據(jù)庫(kù)的指針。</p><p>  在現(xiàn)行系統(tǒng)中,唯一要處理的失敗是事務(wù)的異常中斷。由于內(nèi)存映像在進(jìn)程完成時(shí)被丟棄,在這個(gè)階段并不需要任何復(fù)原方法(recover method)。</p><p>  ?步驟三 : 實(shí)現(xiàn)獨(dú)立性(Isolation)</p>&

29、lt;p>  RM應(yīng)該為每個(gè)事務(wù)適當(dāng)?shù)亟o數(shù)據(jù)加鎖,并當(dāng)事務(wù)完成時(shí)釋放所有加在數(shù)據(jù)上的鎖。你可以試著給數(shù)據(jù)加上不同粒度的鎖。概括地說(shuō),希望你為每個(gè)操作加上可行的最輕粒度的鎖,這樣可以保證最大的并發(fā)性。RM需要恰當(dāng)?shù)亟鉀Q死鎖問(wèn)題:當(dāng)一個(gè)事務(wù)遭遇了死鎖(以LockManager拋出的DeadLockException所指示),RM要強(qiáng)制地中斷這個(gè)事務(wù)的運(yùn)行。</p><p>  ?步驟四 : 實(shí)現(xiàn)持久性(Dura

30、bility)</p><p>  給RM加上持久性和恢復(fù)方法。所有的狀態(tài)都被存儲(chǔ)在磁盤(pán)上(你可以輕松地找到JAVA的java.io.ObjectOutputStream類,它可以把內(nèi)存中的一串?dāng)?shù)據(jù)保存到磁盤(pán)的一個(gè)文件中;相應(yīng)的java.io.ObjectInputStream類作用與之相反)。當(dāng)一個(gè)事務(wù)完成時(shí)磁盤(pán)映象就要做更新。影子方法是用來(lái)保證原子性的:將數(shù)據(jù)庫(kù)的兩個(gè)拷貝保存在磁盤(pán)上,另外還有一個(gè)指向活躍的數(shù)

31、據(jù)庫(kù)的指針。在啟動(dòng)時(shí),RM必須調(diào)用恢復(fù)方法(recover( ))從磁盤(pán)上它的當(dāng)前狀態(tài)恢復(fù)到原有狀態(tài),并且能妥當(dāng)?shù)靥幚砀鱾€(gè)異常,比如調(diào)用未知的事務(wù)標(biāo)識(shí)的操作。</p><p><b>  檢測(cè)RM的方法:</b></p><p>  用多個(gè)客戶端和一個(gè)獨(dú)立的資源管理器來(lái)檢測(cè)這個(gè)簡(jiǎn)易的RM。資源管理器中的Shutdown( )方法用來(lái)檢測(cè)RM是否妥當(dāng)?shù)仃P(guān)閉。所謂妥當(dāng)?shù)仃P(guān)

32、閉,就意味著它要等待所有運(yùn)行的事務(wù)完成,并清理它的文件,以使RM下次啟動(dòng)時(shí),不必恢復(fù)狀態(tài)。Dienow( )方法使RM立即調(diào)用system.exit( ),以模擬一次系統(tǒng)故障,使數(shù)據(jù)庫(kù)停留在它的現(xiàn)行狀態(tài);當(dāng)RM下次重啟時(shí),它將恢復(fù)原有狀態(tài)。dieBeforePointerSwitch() 和dieAfterPointerSwitch()方法設(shè)定標(biāo)記,以便讓RM在下一個(gè)commit操作前調(diào)用system.exit( )。細(xì)節(jié)請(qǐng)參閱API。

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論