2017-06-20 159 views
0

你好,我的問題是,我無法避免緩存。我正在使用彈簧數據Jpa與春季啓動1.5.4Spring Data Jpa - 緩存

我在做什麼: 我有一個情況,當一些客戶端請求我的REST端點與一些數據基於我創建一個實體,我保存它進入數據庫,接下來我請求另一個REST端點,它可以反應我的確定,但是我得到的請求還沒有完成。接下來,我正在等待另一個服務,它需要我的另一個REST端點(第一個客戶端始終在線)。這個端點修改了第一次請求後創建的實體,我在這裏遇到了問題。

基本上,第一個請求創建實體並使用「saveAndFlush」方法保存它。當第一次請求等待另一個線程使用的彈簧數據的JPA修改這個實體:

@Modifying(clearAutomatically = true) 
@Query("UPDATE QUERY ") 
@Transactional 
int updateMethod(); 

但在那之後(當第一個請求從等待釋放)當我打電話的第一個線程findOne方法我上了年紀的實體,我曾嘗試還覆蓋方法:

@Transactional 
default MyEntity findOneWithoutCache(Long id) { 
    return findOne(id); 
} 

但這不是工作壓力太大,我還添加了

@Cacheable(false) 
public class MyEntity { 

,這是不是工作壓力太大。

只有一個這是工作的方式,當我使用@Query這樣選擇該實體:

@Query("SELECT STATEMENT " 
     + "WHERE p.id = ?1") 
MyEntity findEntityById(Long id); 

你能解釋我如何解決這個問題呢?

+0

也許更容易: 線程#1:創建實體和saveAndFlush 線程#2:使用@Query 線程#1更新實體:findOne實體和變老的對象 – pustypawel

+0

如果你使用'@Transactional(傳播= Propagation.REQUIRES_NEW )'在'findOneWithoutCache'方法上? – ledniov

+0

效果相同 – pustypawel

回答

1

事情是什麼樣的事務隔離你有? 什麼數據庫,設置,驅動程序?

理論上,在一個完美的ACID交易中 - 在開始交易後,您無法看到其他交易中所做的更改。 (請參閱可重複讀取)。

另一方面,通常你在ACID中沒有我。隔離度較弱。 (如Read Commited)。

如果查詢起作用,則表明您沒有可重複讀取 - 也許您應該簡單地獲取EnityManager(通過JpaContext)並嘗試清除()會話(在第一個線程中)?

+0

它的工作原理!但告訴我,我遇到你的解決方案還有一件事,但我用刷新方法(什麼是錯的 - 我得到異常TransactionRequiredException)。感謝您的迴應,現在我看到detach方法將會被接受。你能告訴我更多的事情嗎,當我使用@PersistenceContext註解instand的自動裝配JpaContext並使用getEntityManagerByManagedType方法獲取它時,注入entityManager是否有區別? – pustypawel

+0

另一件事 - 爲什麼當事務被提交(結束)時,EntityManager仍然保留舊對象?我錯過了什麼? – pustypawel

+1

@pustypawel,這是第5個關於Stack Overflow的問題的答案。我認爲你該開始接受應得的答案了。請參閱[當某人回答我的問題時該怎麼辦?](https://stackoverflow.com/help/someone-answers)提前致謝。 –