DATAREDIS-673 - Prevent false positive cache hits while Redis keys expire.

We now prevent false positive cache hits after checking for key presence and the Redis key gets removed before fetching its value.
This can happen if we check positively for presence but the key expires (TTL) or gets removed before the GET call is able to fetch the value.

Previously, we returned a RedisCacheElement wrapping null without regard to whether the cache is able to store/return null values. We now inspect the returned value for presence to eagerly return a negative cache hit and to preserve cached null values.

Original Pull Request: #310
This commit is contained in:
Mark Paluch
2018-02-08 14:08:50 +01:00
committed by Christoph Strobl
parent a44bb10a6a
commit 5268549710
2 changed files with 36 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2017 the original author or authors.
* Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -313,6 +313,23 @@ public class RedisCacheUnitTests {
assertThat((String) cache.get(KEY, callableMock), equalTo(VALUE));
verifyZeroInteractions(callableMock);
}
@Test // DATAREDIS-673
@SuppressWarnings("unchecked")
public void getWithCallableShouldReadValueFromCallableWhenKeyGetsDeletedInFlight() throws Exception {
cache = new RedisCache(CACHE_NAME, NO_PREFIX_BYTES, templateSpy, 0L);
Callable<Object> callableMock = mock(Callable.class);
Object result = new Object();
when(callableMock.call()).thenReturn(result);
when(connectionMock.exists(KEY_BYTES)).thenReturn(true);
when(connectionMock.get(KEY_BYTES)).thenReturn(null);
assertThat((String) cache.get(KEY, callableMock), equalTo(VALUE));
verify(callableMock).call();
verify(connectionMock, times(2)).get(KEY_BYTES);
}
@Test // DATAREDIS-468
public void noMultiExecForCluster() {