我想了解Spring的緩存如何工作,特別是與事務和更多線程一起工作。使用事務和並行線程時出現錯誤的Spring緩存狀態
讓我們的服務緩存其結果
public class ServiceWithCaching {
@Cacheable(value="my-cache")
public String find() {
...load from DB
}
@CacheEvict(value="my-cache", allEntries=true)
public void save(String value) {
...save to DB
}
}
現在考慮運行兩個並行線程測試。其中一個使用事務來保存一個值,另一個讀取一個值。
service.save("initial"); // initial state
assert service.find() == "initial"; // load cache
CountDownLatch latch = new CountDownLatch(1);
Thread saveThread = new Thread(() -> {
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, transactionDefinition);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
service.save("test"); // evict cache
latch.await();
}
});
});
saveThread.start();
Thread readThread = new Thread(() -> {
service.find(); // load cache
latch.countDown();
});
readThread.start();
saveThread.join();
assert service.find() == "test";
聲明失敗,因爲service.find()
返回「initial」。這是因爲第二個線程在第一個線程提交事務之前加載先前被驅逐的緩存。
結果是:
- 持久化的價值= 「測試」
- 緩存值= 「初始」
是否有任何春路該怎麼解決這個問題?
也許你的答案在這裏。 http://stackoverflow.com/questions/21467439/multiple-threads-calling-the-cacheable-method-spring-cache-3-2-6-is-allowing – duardito