2011-06-08 109 views
3

上下文:一個用asp.net MVC + NHibernate編寫的web應用程序。這是一種玩家同時玩的紙牌遊戲,因此他們的動作可能會同時修改實體的同一個字段(他們在字段中都會執行x = x + 1)。看起來很經典,但我不知道如何處理它。如何用NHibernate + asp.net mvc處理這種併發情況?

不用說我不能向用戶顯示彈出窗口,說「實體已被其他玩家修改。合併或取消?」。當你認爲這與一張牌的動作有關時,我不能這樣干預。我的應用程序必須在內部處理這種情況。由於該字段位於實體類中,並且每個會話都有自己的實體實例,因此我不能簡單地採用CLR鎖。這是否意味着我應該使用悲觀併發性,以便每個請求都作用於這個實體,直到玩家完成他的行爲爲止?實際上,每個PlayCard請求都應該使用鎖嗎?

請不要將我發送給NH文檔關於併發性或相似性。我是在這種情況下應該使用的技術,而不是如何在NH中實現它。

感謝

+0

聽起來就像你想要一個系統,其中多個用戶都有能力修改實體屬性(在服務器上),沒有任何併發​​問題 - 即沒有鎖,但所有更新成功?這當然是不可能的 - 只有兩種可能性 - 要麼鎖定並且一次只允許1次更新,要麼允許所有更新成功,但接受最後一次更新將覆蓋以前的更新。 – BonyT 2011-06-08 14:00:54

+0

我的直覺是我必須鎖定,不僅是更新,而且是「選擇+更新」序列。否則,我的x = x + 1示例將不起作用。我不能接受併發更新,因爲在初始x = 1的情況下,在所有玩家採取行動後,x將是2而不是3。所以我的問題更多的是「我是否正確地說,讓我們說PlayCard操作,所有的Web請求應該會話鎖定」? – 2011-06-08 14:04:42

+0

我不會在這裏使用數據庫。我會讓客戶端ajax調用服務器 - 它可以允許更新或者根據先前存在的更新來阻止它 - 將原始值與當前值進行比較。服務器端,我會把實體保存在一個單例中以提高響應速度。 – BonyT 2011-06-08 14:18:13

回答

1

你可以嘗試用這種方式來運用樂觀鎖定:

DB實體將有一列跟蹤實體版本(nhibernate.info link)。

如果在保存實體(=由其他用戶修改)時出現「陳舊版本」異常 - 重新加載實體並重試。然後將更新後的值發送給客戶端。

據我所知,您的後端接收來自客戶端的請求,然後打開會話,做一些更改並更新關閉會話的實體。在這種情況下,任何線程都不會在內存中佔用一個實體太長時間,樂觀鎖定衝突不應該經常發生。

這樣可以避免讓許多鎖定的線程等待操作完成。另一方面,如果您期望重試發生的頻率過高,您可以嘗試加載實體時使用SELECT FOR UPDATE鎖定(在NH Get方法中使用LockMode.Upgrade)。雖然我發現這個線程不鼓勵我使用SQL Server:SO link

一般來說,解決方案取決於遊戲的邏輯以及是否可以在不向用戶顯示消息的情況下解決代碼中的併發衝突問題。我還讓UI更新了自己,通過足夠的最新數據來避免玩家採用過時的遊戲情況,然後對結果感到驚訝。

+0

Thx。然而,在我的mvc應用程序中,在請求開始時自動創建會話並在遠端關閉會很困難。獲得一個陳舊的實體意味着這個會話是無用的,所以我將不得不手動重新打開一個會話,這會打破我已有的工作單元。但無論如何,我理解你的邏輯。 – 2011-06-08 15:00:56

+0

嗯,是否有可能將此更改包裝在較小的事務中並嘗試立即提交?如果失敗,則重試。您可以在此期間保持會話打開。不知道你的情況下工作單位有多重要。 – AlexD 2011-06-08 15:19:13

+0

這是否意味着實體必須重新連接到子會話?實體擁有的許多孩子沒有問題? – 2011-06-08 17:32:07

1

根據您的業務邏輯嘗試二級緩存可能有意義。這取決於遊戲的長度和玩法。由於會話工廠級別存在二級緩存,因此會話工廠必須根據遊戲的生命週期進行管理。可以爲每個請求創建一個Nh會話,但由爲二級緩存配置的會話工廠產生意味着所關注的數據緩存在所有會話中。使用二級緩存的好處在於,您可以逐個類地對其進行配置 - 僅緩存您需要的實體。它還根據緩存提供者提供了各種併發策略。儘管這可能會將併發問題從數據庫級別轉移到NH會話,但這可能會給您一個更好的選擇來處理您的情況。有使用這個的陷阱,但它的適用性完全取決於你的業務邏輯。

+0

有趣。我對開始二級緩存一無所知。有關這個主題的有趣的文章? – 2011-06-08 17:31:02

+0

這裏是一篇好文章:http://nhibernate.hibernatingrhinos.com/28/first-and-second-level-caching-in-nhibernate 這裏是NH文檔中的部分: http:// nhforge。 org/doc/nh/en/index.html#performance-cache – stantona 2011-06-08 17:36:06

+0

來自ayende的大文章,thx – 2011-06-10 12:54:37

相關問題