2015-09-30 60 views
0

JPA方法EntityManager#lock是否對內存中的管理實體實例立即生效或只是將語義按需路由到數據庫?在JPA上鎖定實體或數據庫

+1

您鏈接到文檔,其中有一個指向LockModeType的鏈接,該鏈接爲您描述了它:https://docs.oracle.com/javaee/7/api/javax/persistence/LockModeType.html正如它所指出的那樣,發生取決於所使用的鎖定類型以及您的對象是否具有樂觀的版本鎖定。 – Chris

+0

是的,我想是這樣,但它在某種程度上含糊不清。你能否幫助闡述下面的情況? (a)實體被鎖定但數據庫不是; (b)數據庫鎖定但實體沒有; (c)兩者都鎖着;和(d)兩者都不是。 – sof

+1

確實沒有任何不涉及數據庫的鎖定,但如果沒有更具體的示例或情況,我不能更好地解釋它。你的實體是否有樂觀鎖定,以及你在看什麼LockModeType?樂觀鎖使用對象本身內的版本字段,並將更新它,但它是事務性的。它可以通過使當前事務失敗,如果在當前事務不可能發生的情況下被更新,則可以避免問題。悲觀鎖通常使用數據庫選擇更新語義來鎖定行。 – Chris

回答

1

只有在使用悲觀鎖類型之一時,纔會立即使用EntityManager#lock鎖定。

使用悲觀鎖定類型將鎖定指令路由到數據庫,並等待鎖定成功或達到超時。因此,呼叫被阻止,如果不成功,則事務被回滾。

對內存中對象的直接影響是間接的,但是立即 - 如果未獲取鎖定,事務將回滾並且無法成功完成事務。在此之後修改實體對象是沒有意義的,因爲它們不會被持久化。但是從理論上講,可以像使用任何其他普通Java對象一樣修改和使用實體對象,只要您能夠捕獲LockTimeoutException,但我不建議這樣做。

如果您使用樂觀的鎖定,那麼從其性質來看,只有在檢測到衝突後纔會回滾事務。這可能只發生在,此時實體將被持久保存到DB(通常在事務結束時,但也可能在中間刷新期間發生)。樂觀鎖定的關鍵是在稍後明顯發生碰撞的時候阻止鎖定。

有關JPA鎖定機制的非常好的文檔可以在此Locking in JPA頁面找到。