2014-05-14 29 views
0

說一下,如果我想爲一個Multiplex創建一個基於Web的預訂系統,其中有兩個大廳,每個大廳運行4個會顯示一天。我想同步每個節目的座位預訂。Java - 哪一種鎖定方法最適用於預訂系統

  • 人A試圖預留2PM顯示在廳A
  • 人B試圖預留6PM顯示在廳A
  • 人物C試圖預留2PM顯示在B廳
  • 人d試圖儲備2PM秀A館
  • 人ê試圖保留下午6時顯示在B廳

所有這些,我想只有人·d等待一個人完成bookin因爲他們爲相同的大廳和相同的演出時間保留。所有的人應該能夠預定同時

我的業務層方法hallName,showId作爲參數

public int createBooking(String hallName, int showId){ 

    //check if there are any available seats 
    //access DAO layer to create booking 

    return bookingId; 
} 

我無法同步此方法,因爲這將使所有預訂彼此等待。

我不能使用信號量,因爲它不基於參數獲取/釋放鎖定。我不知何故必須在獲取/釋放鎖的同時傳入一個參數,或者根據show id創建一個預訂隊列。 我不想硬編碼鎖的數量,因爲大廳和節目的號碼可能會隨時間而改變。

在Java 6中有辦法嗎? (框架 - 春季3 /服務器 - Websphere7)

可能有一個簡單的方法,但我恐怕我沒有在正確的方向思考。

+2

如果你使用的是數據庫,爲什麼不依靠它來做你的鎖定?此外,請注意,您無法控制人員D是否等待Persion A,反之亦然,或者他們之間是否存在爭用。 – kdgregory

+0

你有沒有考慮過使用演員?每個大廳+節目有一個「預約演員」,可以在系統保持高併發時有效排隊這些請求。見阿卡。 – maasg

+1

我不會使用任何Java同步,但是一旦有人開始預留座位,就爲他們預留座位。如果他們取消了,把它放回可用的座位池中。此外,由於這是基於Web的,因此他們可能會關閉瀏覽器,因此您需要在這些臨時預訂上留下時間戳,並定期發佈超過「X」分鐘的任何內容。 –

回答

0

試試這個

public int createBooking(String hallName, int showId){ 
    synchronized ((hallName + showId).intern()) { 
     //check if there are any available seats 
     //access DAO layer to create booking 
     return bookingId; 
    } 
} 
+0

這看起來很簡單。這種方法的任何問題? –

+1

多年來我在不同的環境中使用過它。這對於實現任意粒度的鎖定條帶化有點不明顯。唯一的問題可能是周圍有非常多的不同的(hallName + showId)字符串,這會在實際使用時耗盡內存。 –

+1

這可以正常工作,直到您決定使用相同的字符串鎖定程序中的其他位置。 – kdgregory

1

你可以看看事件採購,他在現實生活中這樣的事情。這是一種相當典型的這種架構問題。

我不打算在這裏解釋的是整個模型,我甚至會背叛它,以短:

我會創造BookingRequested事件,有一個唯一的ID(UUID也許,或者數據庫 - 提供)和時間戳記,並將它們存儲在數據庫中(或存儲在內存隊列中)。

然後一個查詢處理器會對它們起作用。它可能會鎖定內存中的對象,或者甚至可能決定只有一個線程可以在一個房間中工作,爲此特定房間提取未處理的請求。 如果您不能,並且讓遠程系統處理相同的數據,則解決方案可能是樂觀鎖定。

當您對預訂做出決定時,這是一個新事件,您也將存儲在數據庫中。它將包含原始請求的參考和結果。

微軟有一個免費的pdf「探索CQRS和事件採購」,有一個非常完整的例子,具有類似的上下文(用於在各種會議上預訂場所的系統)。