2017-09-06 74 views
2

Spring Boot Application中的我的服務方法被多個線程訪問,一個線程正在修改數據庫中的數據。在Spring JPA Repository中讀取未被取消的數據

當其他線程在第一次提交之前訪問數據時,它不會獲得早期線程的數據庫更新。

我已經使用了以下注釋到相關的方法後長時間搜索stackoverflow。

import org.springframework.transaction.annotation.Isolation; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED) 
public void accept(Event<String> event) {} 

但是無法達到理想的效果。未提交的更改不會在第二個線程中檢索。

請幫我解決這個問題。

我已經使用實體管理器flush()方法,但它不成功。

+2

數據庫支持哪些隔離級別?更重要的是,爲什麼你想要另一個線程讀取未提交的數據?豈不是更好呢? – takteek

+1

如果您需要訪問由第一個線程修改的數據,那麼您的事務依賴於彼此。 「READ UNCOMMITTED」不是解決這個問題的方法。你正在寫/讀什麼樣的數據,爲什麼你需要在提交之前訪問它? – Kayaman

+0

其實在第一個線程上,我對數據庫中的特定數據進行了鎖定。所以當它被一個線程訪問時,它不應該被其他人訪問。在我的方法中,首先獲取解鎖的數據併爲其鎖定並提交給數據庫。所以其他線程不應該選擇這些條目。但不幸的是,他們選擇相同的條目,因爲他們還沒有提交給數據庫。 – user3011958

回答

1

您正在混合隔離級別和鎖定。

隔離級別READ_UNCOMMITTED允許其他事務查看您的第一個事務在提交之前寫入的內容。它不需要這種情況發生,也不會影響鎖。但根據您的意見,您真正想要實現的目標是以某種方式正確鎖定數據庫行,以便其他人無法訪問它們。

的JPA的方法來做到這將是查詢與適當的鎖定模式的數據:

鎖定模式可以被EntityManager鎖定方法的裝置,所述的EntityManager,查詢和TypedQuery的方法中指定的允許指定鎖定模式的接口以及NamedQuery註釋。

(3.4.4從JPA Specification

您是在「悲觀」變體防止其他事務讀取鎖定行,他們將致力於(並因此鎖定解除)之前

可能感興趣

如果事務T1調用鎖(實體,LockModeType.PESSIMISTIC_READ)或鎖(實體,LockModeType.PESSIMISTIC_WRITE)onanobject,EntityManager的必須確保既不的以下現象,可能會發生:

  • P1(髒讀):事務T1修改一行。另一個事務T2然後在T1已提交或回滾之前讀取該行並獲取修改後的值。
  • P2(不可重複讀取):事務T1讀取一行。在T1已提交或回滾之前,另一個事務T2會修改或刪除該行。
(從 JPA Specification 3.4.4.2)

您可以通過使用@Lock標註使用與Spring數據JPA這些鎖模式。