2011-06-16 36 views
1

我正在使用Wicket和自定義的PageAuthorizationStrategy訪問數據庫以獲取有關當前用戶的信息,從而訪問他的訪問權限。每個請求都被Spring Open-Session-In-View過濾器打包以打開/關閉Hibernate會話。檢票,身份驗證和事務劃分

這對讀取數據庫非常有效。無論何時需要寫操作,我都會調用使用Spring的基於註釋的事務處理的服務層。這也適用,但我認爲這是一個特定的錯誤的原因:當一個對象在請求A中進行身份驗證期間加載,然後在另一個請求B中進行修改,然後切換到請求A中的服務層時,服務層正在處理錯誤的值,因爲Hibernate和底層數據庫都不能確保隔離。由於我一直在努力與數據庫/交易理論的具體細節,請糾正我,如果這個假設已經是錯誤的。

我的解決方案的第一個想法是在寫入事務啓動後刷新爲加載身份驗證的對象。儘管當由服務修改的對象同時需要認證時,這會引起問題。當Wicket使用表單中的變化數據填充對象並在提交方法中將其傳遞給服務時(例如),就會發生這種情況。

所以很可能,這樣做的正確方法是確保身份驗證代碼已被包裝在與可能在同一請求期間執行的任何寫入代碼相同的事務中。

我該如何解決這個Wicket中的「正確方法」?

編輯:這個問題變得更加的問題,因爲我意識到,當事務服務方法在引發異常後回滾時,視圖層會導致LazyInitializationException。顯然,Spring的TransactionManager會清除會話和/或Hibernate/Spring深處的其他內容,因爲我可以從數據庫重新加載對象,但試圖加載包含在該對象中的集合導致所述異常。任何想法如何去做這件事?如果有一種使用「每次請求一次處理」的優雅方式,我想這一切都將得到解決。

回答

1

這不是一個問題檢票補償的變化,但DB/Hibernate的問題。對於樂觀和悲觀策略,Hibernate有support

optimistic approach包括向實體添加一個version字段,該字段在刷新更新時將進行驗證,如果該記錄已被某人修改,則會導致異常。

pessimistic approach使用數據庫支持鎖定記錄,避免併發修改。

兩者都有優點和缺點,並且都將要求您主動使用相應的功能和代碼,以使其工作(沒有魔法灰塵)。

樂觀主義者將不得不在任何地方處理異常。

悲觀者將不得不處理爭用和可擴展性問題。

樂觀主義者可能不得不改變模式結構和/或領域模型來處理某些情況。

悲觀主義者在處理該表的更新時必須經常擔心鎖定(您忘記鎖定在一個地方,而您剛剛創建了heisenbug)。

NoSQL人會告訴他們完全放棄關係數據庫,並且沒有模式,事務和一致性(順便提一下,在大多數情況下是愚蠢的),他們生活得很開心。

1

我不知道這是即使在檢票「正道」的問題時,我會嘗試在服務/ DAO層來解決這個問題,有喜歡的一些可能性:

  • 不使用OSIV模式獲得「實時」所需的信息,當在表格上使用時,OSIV發光顯示項目信息而不需要查詢數據庫
  • 將編輯/更改的屬性附加到對象上次更改的時間戳,任何寫操作之前,你可以檢查時間戳和警告/從「未來」