@Transactional中的隔離和傳播參數
在Spring的@Transactional註解中,兩個關鍵參數定義了資料庫事務的行為:隔離和傳播。本文探討了何時以及為何應考慮調整其預設值。
傳播
傳播定義了事務如何相互關聯。常見選項包括:
預設值: 必需
預設值: 必需
隔離SERIALIZABLE: 最強隔離,確保無資料衝突。
預設值: 因資料庫而異(例如,MariaDB 的REPEATABLE_READ)
實際範例Thread 1 Thread 2 | | Write(x) | | | | Read(x) | | Rollback | | | Value (x) is now dirty (incorrect)
考慮髒讀問題,其中一個事務可以讀取另一個事務所所做的未提交的變更。 線程 1 線程 2 | | 寫(x) | | | | 讀(x) | | 回滾 | | | 值(x) 現在是髒的(不正確)在這種情況下,為了防止髒讀,您可以將隔離等級設為
READ_COMMITTED並將傳播等級設為REQUIRED。這種組合確保事務只讀取其他事務已提交的資料。
自訂事務
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
repo1.retrieveFoo();
repo2.retrieveFoo();
}
方法始終在新事務中運行,確保其他並發任務所做的任何更改不會幹擾其執行:@Transactional(propagation=Propagation.REQUIRES_NEW) 公共無效提供服務(){ repo1.retrieveFoo(); repo2.retrieveFoo(); }
測試事務行為@Test
public void testProvideService() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
fooService.provideService();
transactionManager.rollback(status);
// Assert repository values are unchanged ...
}
要驗證不同傳播層級的行為,可以使用 Java 測試:@Test 公共無效testProvideService(){ TransactionStatus 狀態 = transactionManager.getTransaction(new DefaultTransactionDefinition()); fooService.provideService(); transactionManager.rollback(狀態); // 斷言儲存庫值未更改... }使用 REQUIRES_NEW,
fooService.provideService() 不會回滾,因為它在單獨的事務中操作。使用REQUIRED
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3