簡體   English   中英

按請求可變事務隔離級別

[英]Variable transaction isolation levels by request

我正在編寫一個小拍賣應用程序,並且確定地記錄我的出價非常重要。 畢竟,拍賣的最后幾秒對買家來說是關鍵時刻,我不能冒險讓他們同時出價和競爭。

當然,這就是事務隔離的用途。 我可以將我的隔離級別設置為可序列化,我們都設置好了。

但是所有其他請求呢? 如果人們正在查看個人資料或發送消息,則這些請求不需要接近這種事務隔離的任何地方。 對於這些請求,讀提交隔離級別是完全可以接受的。

我正在將我的事務級別設置為我的休眠屬性hibernate.connection.isolation ,但我真的希望能夠為每個請求執行session.setTransactionIsolation(newIsolation)

如果您使用的是 Spring,則可以使用以下內容:

@Transactional(isolation = Isolation.SERIALIZABLE)

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

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

因為大多數數據源實現只能采用默認的事務隔離級別,所以我們可以有多個這樣的數據源,每個數據源服務於特定事務隔離級別的連接。

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

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

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

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

使用分離的實體時,樂觀鎖定 6 的擴展性更好(在邏輯事務啟動時加載它們)。

Session session = getSession(dataSource, sessionFactory, Connection.TRANSACTION_SERIALIZABLE);

public Session getSession(DataSource dataSource, SessionFactory sessionFactory, int isolationLevel){

  // Get connection from current dataSource and set new isolation
  Connection connectionWithNewIsolation = dataSource.getConnection();
  connectionWithNewIsolation.setTransactionIsolation(isolationLevel);

  // Get session from current sessionFactory with the new isolation
  Session session = sessionFactory.openSession(connectionWithNewIsolation);

  // Hibernate 4.3
  //SessionFactory.openStatelessSession(Connection connection)
  // Hibernate 3.6
  //SessionFactory.openSession(Connection connection)
  //SessionFactory.openStatelessSession(Connection connection)

  return session;
}

對於這種情況,我將在您的出價對象中使用樂觀鎖......競爭條件仍然會發生,但是當事務嘗試提交您的域對象的更改時會被檢測到(如果讀取的版本已更新,則會引發異常通過另一個線程)。

因此,對任何出價對象的任何更改都幾乎是可序列化的(我說“幾乎”是因為為了可序列化,需要捕獲失敗的交易並以某種方式重試)。

如果為每個事務設置隔離級別失敗,您始終可以在代碼中手動序列化特定操作(同步、信號量等)。 但是請記住它不可擴展(單個 jvm,單個操作,容易被其他部分的代碼意外繞過)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM