2013-07-08 70 views
4

我目前正在構建一個Web應用程序(適度現代),可以對數據庫執行一些簡單的數據修改操作。我正在考慮潛在的問題。Web應用程序:並行更改數據庫中的數據

假設用戶登錄到Web應用程序並從存儲庫加載一些數據。 (S)他更改數據,然後想將其寫回數據庫。

如何防止以標準化方式如下場景:

  • 他(她)登錄兩次,已經從第一屆保存時會丟失第二會話保存一些數據。
  • 其他一些用戶加載了數據,現在正在更改它,他們可能會覆蓋我們的更改。

我不想說2階段提交,我不打算推​​出我自己的版本。防止同一用戶登錄兩次(用戶單例),再加上嚴格的權限管理可以解決第一個問題。但是,如果業務需求允許多個代理查看和更改相同的數據,我仍然處於虧損狀態。

是否有差異庫/算法測試想要寫入的數據之前,如果讀取期間的假設持有?對於大型商業應用,這通常如何解決?

回答

3

我想兩個主要策略之間進行選擇:

  • 樂觀鎖
  • 悲觀鎖定

樂觀鎖:保存一個版本(號),在你的對象的ID一起存儲庫(數據庫)。在保存新對象之前,請檢查您要覆蓋的舊對象的版本。如果版本與編輯對象的版本不匹配,則中止保存並向用戶報告存儲庫中的對象已更改。如果版本匹配,則使用新版本覆蓋舊對象並增加版本。

悲觀鎖定:在用戶開始更改它之前鎖定對象。如果對象已被鎖定,則顯示消息,即當前對象正在被另一個用戶編輯。 這可以在使用DB鎖定的單個事務中完成,也可以使用有狀態的bean或使用單獨的使用定義字段。

悲觀鎖定實現起來比較複雜,但它提供了更好的用戶體驗,因爲如果發生樂觀鎖定異常,它會阻止用戶輸入數據並再次重新輸入。

有關更多信息,請參閱http://docs.oracle.com/javaee/6/tutorial/doc/gkjhz.html

+0

我可以通過「樂觀鎖定」中的「你」來看到,你指的是一個bean,它使得事情變得更容易。這似乎是一個合理的解決方案。 – 0xCAFEBABE

+0

你是對的! –

0

在大多數情況下(我的意思是幾乎所有的應用程序),這是通過使用ACID database(如Oracle,MySQL和PostgreSQL)完成的。

+0

在Web應用程序上下文中,是否仍然需要分佈式事務協議? – 0xCAFEBABE

+0

@ 0xCAFEBABE:當然不是。人們花很多錢說Oracle的原因是因爲它爲你做到了。接受的答案中提到的JPA API也委託給數據庫。在這裏閱讀本文。它討論了現代數據庫如何進行併發控制:http://en.wikipedia.org/wiki/Multiversion_concurrency_control –

+0

我正在研究MVCC,謝謝Enno。 – 0xCAFEBABE

相關問題