[Java] 按請求變化的事務隔離級別


Answers

如果你使用Spring,你可以使用這樣的東西:

@Transactional(isolation = Isolation.SERIALIZABLE)

它適用於JpaTransactionManager 。 如果您使用的是JtaTransactionManager,則不會傳播請求範圍事務隔離,因為這是默認的JTA行為。

由於JTA不支持事務範圍的隔離級別,因此Spring在使用應用程序服務器JTA數據源時提供了IsolationLevelDataSourceRouter來克服這個缺點。

因為大多數DataSource實現只能採用默認的事務隔離級別,所以我們可以擁有多個這樣的DataSource,每個DataSource都為特定的事務隔離級別提供連接。

邏輯事務(例如@Transactional)隔離級別設置由IsolationLevelDataSourceRouter進行內部檢查,因此連接獲取請求被委託給一個特定的DataSource實現,該實現可以為具有相同事務隔離級別設置的JDBC連接提供服務。

因此,即使在JTA環境中,事務隔離路由器也可以提供獨立於供應商的解決方案,以每個事務為基礎覆蓋缺省數據庫隔離級別。

Java EE不支持方法級事務隔離配置。

SERIALIZABLE隔離級別將保護您免受不可重複的讀取和幻像讀取,甚至SERIALIZABLE也不能保護您免受跨多請求邏輯事務的丟失更新

當使用分離的實體時, 樂觀鎖定縮放比較好(當邏輯事務已經開始時,它們被加載)。

Question

我正在寫一個小小的拍賣應用程序,確保我的出價是非常重要的。 畢竟,拍賣的最後幾秒鐘是買家的關鍵時刻,我不能冒險讓他們同時競標和競爭狀態。

當然,這是事務隔離的目的。 我可以將我的隔離級別設置為可序列化,並且我們都設置了。

但所有其他要求呢? 如果人們正在查看配置文件或發送消息,那麼這些請求不需要靠近這種事務隔離的地方。 讀取提交隔離級別完全可以接受這些請求。

我設置我的事務級別作為我的hibernate屬性hibernate.connection.isolation ,但我真的希望能夠做每個請求session.setTransactionIsolation(newIsolation)




如果設置每個事務的隔離級別失敗,則可以隨時在代碼中手動序列化特定操作(同步,信號量等)。 但是請記住它不可擴展(單個jvm,單個操作,容易被其他代碼忽略)