0

我想了解'Hibernate會話不是線程安全的'的含義。我已經知道了(如果我錯了,請糾正我):休眠會話和線程安全

  1. 在非JTA環境中的會話保存在Thread Local中。所以它被綁定到當前線程。
  2. 在新線程中調用getCurrentSession()會將新會話與其自己的線程本地關聯。
  3. 假設我們在2個線程(T1,T2)之間共享一個實體,在T1中加載並在T2中使用,我們可能會遇到延遲加載等問題,因爲T1和T2中的會話不同。

這解釋了在不同會話之間共享實體時可能會出現什麼問題。

我無法理解的是當一個會話在2個或更多線程之間共享時可能出現的問題。我知道Session中的方法不是線程安全的,會導致競爭條件等,但不清楚如何?如果有人能夠用示例進行解釋或列出一個或多個場景來澄清,我將不勝感激。

在此先感謝

回答

2

Java memory model有非常嚴格的規定:

  • 線程間的內存可視性
  • 線程操作重新排序

Session對象不是線程安全的,這意味着它從來不打算被多個線程訪問。爲此,它使用NO線程安全機制:

  • 沒有互斥
  • 無揮發性讀取
  • 沒有同步

如果你在兩個線程之間共享一個Hibernate會話,然後一個線程變化可能對某些其他線程不可見(沒有正確的同步或易失性讀取)。

每個Hibernate Session都獲得一個關聯的JDBC連接(即使JTA激進版本最終將一個JTA事務DataSource所發佈的所有語句重複使用相同的JDBC連接)。一個JDBC連接不應該被兩個線程訪問,因爲每個線程都應該綁定到一個且只有一個數據庫事務。

+0

謝謝弗拉德。有沒有一個例子或應用場景如何可能出錯?這將進一步幫助我。 – Mustafa 2015-02-11 16:24:25

+0

我沒有任何示例,但您可以輕鬆地自行嘗試。 – 2015-02-11 16:44:04