2010-12-17 11 views
6

Estoy usando el decorador de EhCache SelfPopulatingCache y tengo un problema cuando el caché intenta cargar una nueva entrada, pero es inexistente (es decir, no existe en la base de datos). Entonces, la memoria caché pondrá un valor de null en la memoria caché, para desbloquear cualquier otro que ingrese la clave, pero luego la siguiente cadena hará la misma llamada a la base de datos porque recibió 'nulo' de la memoria caché. lo que significa que piensa que la entrada debe cargarse, aunque en realidad es nula porque los datos no existen en ninguna parte. Siento que estoy haciendo algo mal.Ehcache - using SelfPopulatingCache cuando los datos no están presentes

(pseudo código)

Value v = cache.get(key); // multiple threads will block here 
if (v == null) 
    cache.put(key, getValueFromDB()); // this might put a null value 

Mi solución actual es la de no poner nula, pero para poner un marcador de posición Object y compruebe por ello.

Value v = cache.get(key); 
if (v == null) 
    cache.put(key, getValueFromDB()); 
else if (v == NOENTRYOBJECT) 
    return null; 
else 
    return v; 

¿Pensamientos?

+0

No tengo claro cómo se relaciona su pseudocódigo con 'SelfPopulatingCache'. ¿Cómo estás usando eso? – skaffman

+0

caché = SelfPopulatingCache (o BlockingCache) ... pensó que era bastante claro – Gandalf

Respuesta

3

Hacemos algo similar. En nuestro caso, ingresamos Boolean.FALSE en la memoria caché si la clave solicitada no corresponde a un elemento válido. Básicamente le dice al código de llamada que la clave que solicitó no coincide con ningún dato. Debe hacer una llamada al db en la primera solicitud de esa clave para descubrir que no se corresponde con los datos válidos, pero las llamadas posteriores se salvan de la búsqueda db. Por supuesto, si alguna vez se ingresan datos en el DB de esa clave, debe asegurarse de invalidar esa entrada de caché (de lo contrario, devolverá Boolean.FALSE aunque haya datos reales disponibles).

No estoy seguro si mi respuesta ayuda mucho (no es un enfoque alternativo), pero al menos confirma que no está solo en su enfoque.

Por cierto, no creo que esto sea exclusivo de SelfPopulatingCache de EHCache.

1

El patrón típico es que no vuelva a comprobar la base de datos si existe el elemento de CLAVE en la memoria caché en absoluto, en lugar de la VALOR.

El patrón se describe en los documentos ehcache aquí: Caching Empty Values.

lo general, pero no siempre, get devuelve un Element, por lo get(id) no será nulo si put(id, value) fue llamado alguna vez con anterioridad, incluso si el valor es nulo.

Tenga en cuenta que esto depende de la implementación de la memoria caché. La documentación de ehcache parece sugerir que siempre debería funcionar, pero BlockingCache (y sus descendientes) does NOT allow putting null values into the cache. El objeto base ehcache Cache permite que los valores nulos se almacenen en la memoria caché (al igual que muchos ejemplos e implementaciones personalizadas).

Creo que la solución que ya tiene (objeto de valor de marcador de posición) también funciona y debería obtener el mismo resultado que la clase base Cache de ehcache y la documentación.

+0

En realidad eso no es cierto: si nos fijamos en el código de BlockingCache y el método put (..) - si value == null quita la clave del cache. Entonces put (id, null) efectivamente no pone nada en el caché, el siguiente get para id devolverá null - not y Element. – Gandalf

+0

Hmmm. No he visto el código, así que esa sería la fuente definitiva. Pero eso parece contradecir completamente la documentación de Ehcache. No estoy seguro de qué otra cosa funcionaría el ejemplo de "Almacenamiento en caché de valores vacíos" si no puede almacenar en caché un valor nulo (explícitamente le dice que haga eso). Voy a mirar más de cerca el código cuando tenga oportunidad, pero * pienso * Recuerdo haber hecho eso en el pasado y funcionó bien (no estoy seguro de que te acuerdes, recuerdo vago, también escribiré una prueba simple para confirmar /negar). –

+0

Veo lo que es. La implementación de mi caché no usa ninguna de las implementaciones de Ehcache incorporadas, o por supuesto, la opción de autoopulación de caché. Mi método put usa un valor booleano que se establece en la implementación de caché llamada: putNullInCache. Por defecto es verdadero, y así permite poner para almacenar nulo. Por lo tanto, depende de la impl del caché, y tiene toda la razón sobre SelfPopulatingCache. Actualizaré mi "respuesta" solo para referencia futura para cualquier persona cuando tenga la oportunidad, pero de hecho es incorrecta;). En general, creo que lo que estás haciendo tiene el mismo efecto neto de todos modos. –

0

Estoy pensando que necesita mirar en la CacheElementFactory. Lo había implementado en primavera para un proyecto en el que estaba trabajando para exigir que se cargue información en el caché; si se produjo un error en el caché, se intentó cargarlo desde la base de datos. Sin embargo, no recuerdo específicamente qué hice con esto y creo que esto desafortunadamente resultaría en una solicitud a la base de datos para cada pase que solicitó la clave faltante.

Cuestiones relacionadas