2011-11-18 47 views
1

假設我的Web服務器收到兩個同時請求。兩個併發請求,相同的JPA實體 - 問題?

它會在一個單獨的線程中處理每個請求。

它會爲每個線程創建一個JPA實體管理器。

現在我們假設每個線程請求相同的數據庫行。假設我有一張名爲Cars的表。我有一輛id = 5的汽車。我在兩條線上都找到了id = 5的汽車。

所以我現在有兩個獨立的對象代表同一個實體。

現在我們假設我在線程1中更新了汽車的gasLevel。如果我在線程2中得到gasLevel,是否會得到由線程1設置的新gasLevel?

回答

6

不,你不會,因爲如你所說,你有兩個不同的實體實例。如果他們都將gasLevel更新爲不同的值,那麼最後的提交將會獲勝。

這就是實現樂觀鎖定的原因之一,它使用@Version註解的版本字段:最後一次提交會失敗,因爲其他事務已經更新了實體加載和新狀態出現之間的值酡。

請注意,即使線程1讀取值(7),將其更改爲8,刷新和線程2讀取值,線程2在默認情況下仍將看到7,因爲缺省情況是使用READ_COMMITTED隔離級別。這意味着一個事務只能看到其他事務已經提交的數據。不過,這取決於數據庫。例如HSQLDB只支持READ_UNCOMMITTED。

+0

也許你的意思是一些舊版本的HSQLDB。簡單檢查HSQLDB(v2.2是最新的)的用戶指南已將READ_COMMITTED作爲默認值(當然也是2.0版本,可能是1.8 - 儘管1.7絕對不支持它) – DataNucleus

+0

好的,謝謝。我有一段時間沒有用過它。 –

+0

線程1是否有任何方式顯式鎖定對該行的訪問,意味着它有意修改該行,以便在線程1提交之前線程2無法讀取該行的值? – Alexandre

相關問題