我應該在ASP.NET MVC應用程序的相應控制器中將調用包裝爲與try-catch
塊(旨在捕獲/處理StaleObjectStateException
)的存儲庫或應該發生在存儲庫實現內?在哪裏處理StaleObjectStateException
另外我該如何處理異常情況,通知用戶。據我瞭解,沒有回滾是滿意的?
謝謝!
我應該在ASP.NET MVC應用程序的相應控制器中將調用包裝爲與try-catch
塊(旨在捕獲/處理StaleObjectStateException
)的存儲庫或應該發生在存儲庫實現內?在哪裏處理StaleObjectStateException
另外我該如何處理異常情況,通知用戶。據我瞭解,沒有回滾是滿意的?
謝謝!
問題歸結爲一個不同的問題:在哪裏以及如何處理實體的併發修改?即:用戶A和用戶B編輯相同的記錄,並且當稍後保存記錄的用戶(用戶B)獲取StaleObjectStateException時,因爲他編輯的版本現在已過期。
這裏有一些想法:
強行使用戶的版本B的「正確」的一個蠻力,例如通過從數據庫中檢索當前版本的記錄,並將用戶B版本的整個狀態應用到數據庫中。如果用戶A發生了變化,則這是有問題的。 「電子郵件地址」字段和用戶B已更改「用戶名」字段。用這種方法,用戶A所做的一切都消失了。在這種方法中,您會捕獲StaleObjectStateException並修復存儲庫中的所有內容。 「智能」方法:與方法1類似,一切都在存儲庫內部固定(即完全捕獲和處理StaleObjectStateException),但它使用領域知識來選擇性地僅應用用戶B所做的一些更改。例如。如果用戶A更改了電子郵件地址,並且用戶B更改了用戶名,則這些更改不會互相排斥,因此存儲庫只能更新電子郵件地址。如果記錄的兩個方面同時發生變化,而這兩個方面並不直接相互依賴,那麼這很有效。根據你想要的「聰明」,實施這個解決方案可能相當複雜。
拒絕存儲庫內的併發更改。在這種情況下,如果發生StaleObjectStateException,存儲庫需要報告它無法保存記錄。它實際上可能只是讓異常冒出來,但是然後你將NHibernate泄漏到例如控制器。相反,您可以將自己的例外情況與對您的域有意義的更多有用的詳細信息相提並論。在這種情況下,控制器是捕捉異常的好地方。然後,您有什麼做不同的選擇,例如:
雖然這超出了你的問題,我希望這仍然可以幫助你。
如果您正確使用DI將這種異常管理放在控制器中將會打破您對問題的分離。
控制器屬於表示層,表示層不知道你用於數據存儲的是什麼,StaleObjectStateException是NHibernate的東西。