提交 ef95fc2f 编写于 作者: S Stas Volsky 提交者: Stephane Nicoll

Synchronize clear on TransactionAwareCacheDecorator

Previously, a cache decorated with TransactionAwareCacheDecorator would
clear the cache immediately, even when a transaction is running. This
commit updates the decorator to synchronize to the afterCommit phase for
the clear operation as well.

Issue: SPR-12653
上级 6b3092c2
...@@ -22,17 +22,18 @@ import org.springframework.transaction.support.TransactionSynchronizationManager ...@@ -22,17 +22,18 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Cache decorator which synchronizes its {@link #put} and {@link #evict} operations with * Cache decorator which synchronizes its {@link #put}, {@link #evict} and {@link #clear}
* Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager}, * operations with Spring-managed transactions (through Spring's {@link TransactionSynchronizationManager},
* performing the actual cache put/evict operation only in the after-commit phase of a * performing the actual cache put/evict/clear operation only in the after-commit phase of a
* successful transaction. If no transaction is active, {@link #put} and {@link #evict} * successful transaction. If no transaction is active, {@link #put}, {@link #evict} and
* operations will be performed immediately, as usual. * {@link #clear} operations will be performed immediately, as usual.
* *
* <p>Use of more aggressive operations such as {@link #putIfAbsent} cannot be deferred * <p>Use of more aggressive operations such as {@link #putIfAbsent} cannot be deferred
* to the after-commit phase of a running transaction. Use these with care. * to the after-commit phase of a running transaction. Use these with care.
* *
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Stas Volsky
* @since 3.2 * @since 3.2
* @see TransactionAwareCacheManagerProxy * @see TransactionAwareCacheManagerProxy
*/ */
...@@ -108,7 +109,17 @@ public class TransactionAwareCacheDecorator implements Cache { ...@@ -108,7 +109,17 @@ public class TransactionAwareCacheDecorator implements Cache {
@Override @Override
public void clear() { public void clear() {
this.targetCache.clear(); if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
targetCache.clear();
}
});
}
else {
this.targetCache.clear();
}
} }
} }
...@@ -128,4 +128,31 @@ public class TransactionAwareCacheDecoratorTests { ...@@ -128,4 +128,31 @@ public class TransactionAwareCacheDecoratorTests {
assertNull(target.get(key)); assertNull(target.get(key));
} }
@Test
public void clearNonTransactional() {
Cache target = new ConcurrentMapCache("testCache");
Cache cache = new TransactionAwareCacheDecorator(target);
Object key = new Object();
cache.put(key, "123");
cache.clear();
assertNull(target.get(key));
}
@Test
public void clearTransactional() {
Cache target = new ConcurrentMapCache("testCache");
Cache cache = new TransactionAwareCacheDecorator(target);
Object key = new Object();
cache.put(key, "123");
TransactionStatus status = txManager.getTransaction(new DefaultTransactionAttribute(
TransactionDefinition.PROPAGATION_REQUIRED));
cache.clear();
assertEquals("123", target.get(key, String.class));
txManager.commit(status);
assertNull(target.get(key));
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册