Tengo problemas para entender cuándo la hibernación llega al caché de segundo nivel y cuándo invalida el caché.
Esto es lo que entiendo actualmente:
- El caché de segundo nivel almacena entidades entre sesiones, el alcance es SessionFactory
- Tienes que decir qué entidades almacenar en caché, ninguna entidad se almacenará en caché de forma predeterminada
- La caché de consultas almacena los resultados de las consultas en la caché.
Lo que no entiendo es
- ¿Cuándo llega la hibernación a este caché?
- Digamos que he configurado la caché de segundo nivel pero no la caché de consultas. Quiero almacenar en caché a mis clientes, hay 50000 de ellos. ¿De qué manera puedo recuperar los clientes del caché?
- Supongo que puedo obtenerlos por identificación desde el caché. Eso sería fácil pero tampoco digno de almacenar en caché. Pero, ¿y si quiero hacer algún cálculo con todos mis clientes? Digamos que quiero mostrar una lista de los clientes, ¿cómo puedo acceder a ellos?
- ¿Cómo obtendría todos mis clientes si el almacenamiento en caché de consultas está deshabilitado?
- ¿Qué pasaría si alguien actualizara a uno de los clientes?
- ¿Ese cliente quedaría invalidado en la caché o todos los clientes quedarían invalidados?
¿O estoy pensando que el almacenamiento en caché está totalmente mal? ¿Cuáles serían los usos más apropiados de la caché de segundo nivel en ese caso? La documentación de hibernación no es del todo claro cómo funciona el caché en realidad. Solo hay instrucciones sobre cómo configurarlo.
Actualización: he llegado a comprender que la caché de segundo nivel (sin la caché de consultas) sería buena para cargar datos por id. Por ejemplo, tengo un objeto de usuario que quiero verificar los permisos en cada solicitud en una aplicación web. ¿Sería este un buen caso para reducir el acceso a la base de datos almacenando en caché al usuario en el caché de segundo nivel? Al igual que almacenaría la identificación del usuario en la sesión o en cualquier lugar y cuando necesite verificar los permisos, cargaría el usuario por su identificación y verificaría los permisos.
Respuestas:
En primer lugar, hablemos del caché de nivel de proceso (o caché de segundo nivel como lo llaman en Hibernate). Para que funcione, debes
Le indica al proveedor de caché cuántos objetos debe almacenar y cuándo / por qué deben invalidarse. Entonces, digamos que tiene una entidad de Libro y una de Autor, cada vez que las obtenga de la base de datos, solo las que no estén en la caché se seleccionarán de la base de datos. Esto aumenta el rendimiento de manera significativa. Es útil cuando:
Entonces, ¿cuándo funciona el caché?
session.get()
osession.load()
el objeto que fue seleccionado previamente y reside en caché. La caché es un almacenamiento donde ID es la clave y las propiedades son los valores. Entonces, solo cuando existe la posibilidad de buscar por ID, puede eliminar el acceso a la base de datos.Pero no funciona cuando:
from Authors where name = :name
entonces no ingresa a la caché.where id = ?
).fetch="join"
, esto significa que para cargar asociaciones, las uniones se usarán en todas partes en lugar de las declaraciones de selección separadas. La caché de nivel de proceso funciona en objetos secundarios solo sifetch="select"
se usa.fetch="select"
pero luego en HQL usa combinaciones para seleccionar asociaciones, esas combinaciones se emitirán de inmediato y sobrescribirán lo que haya especificado en hbm.xml o anotaciones.Ahora, sobre la caché de consultas. Debe tener en cuenta que no es una caché separada, es una adición a la caché de nivel de proceso. Digamos que tiene una entidad País. Es estático, por lo que sabe que siempre habrá el mismo conjunto de resultados cuando diga
from Country
. Este es un candidato perfecto para el caché de consultas, almacenará una lista de ID en sí mismo y la próxima vez que seleccione todos los países, devolverá esta lista al caché de nivel de proceso y este último, a su vez, devolverá objetos para cada ID. ya que estos objetos ya están almacenados en la caché de segundo nivel. La caché de consultas se invalida cada vez que cambia algo relacionado con la entidad. Entonces, digamos que lo configurófrom Authors
para ser colocado en un caché de consultas. No será efectivo ya que el autor cambia con frecuencia.fuente
En realidad, es útil tener un caché distribuido de valor clave; eso es lo que es Memcached, y funciona con Facebook, Twitter y muchos más. Pero si no tiene búsquedas por id, entonces no será muy útil.
fuente
Llegó tarde a la fiesta, pero quería responder sistemáticamente a estas preguntas que hacen muchos desarrolladores.
Tomando su pregunta una por una aquí está mi respuesta.
R. La caché de primer nivel está asociada con el objeto de sesión . La caché de segundo nivel está asociada con el objeto Session Factory . Si el objeto no se encuentra en el primero, se verifica el segundo nivel.
R. Obtuviste esa respuesta en tu actualización. Además, el caché de consultas almacena solo la lista de ID del objeto y esos Objetos con sus ID se almacenan en el mismo caché de segundo nivel. Entonces, si habilita la caché de consultas, utilizará el mismo recurso. Genial, ¿verdad?
A. Respondido arriba.
A. Respondido arriba.
R. Hibernate no tiene idea, pero podría usar otras memorias caché IMDG / distribuidas de terceros para implementarlas como caché de segundo nivel de hibernación y invalidarlas. Por ejemplo, TayzGrid es uno de esos productos y supongo que hay más.
fuente
El caché de segundo nivel de Hibernate es un poco complicado de entender e implementar. Esto es lo que podemos decir en función de sus preguntas:
Como sugiere, la caché Hibernate L2 (si está habilitada; no está activada de forma predeterminada) se consulta solo después de la caché L1. Se trata de una caché de clave-valor cuyos datos se conservan en varias sesiones.
El almacenamiento en caché de consultas sería lo mejor para este caso de uso, ya que los datos del cliente son estáticos y se recuperan de una base de datos relacional.
Depende de la estrategia de caché de Hibernate específica que esté utilizando. Hibernate en realidad tiene cuatro estrategias de caché diferentes:
READ_ONLY : Los objetos no cambian una vez dentro del caché.
NONSTRICT_READ_WRITE : Los objetos cambian (eventualmente) después de que se actualiza la entrada correspondiente de la base de datos; esto garantiza una eventual consistencia.
READ_WRITE : Los objetos cambian (inmediatamente) después de que se actualice la entrada correspondiente de la base de datos; esto garantiza una fuerte consistencia mediante el uso de cerraduras "blandas".
TRANSACCIONAL : Los objetos cambian mediante transacciones XA distribuidas, lo que garantiza la integridad de los datos; esto garantiza el éxito total o revertir todos los cambios. Sin embargo, en los cuatro casos, la actualización de una sola entrada de la base de datos no invalidaría la lista completa de clientes en la caché. Hibernate es un poco más inteligente que eso :)
Para obtener más información sobre cómo funciona el almacenamiento en caché L2 en Hibernate, puede consultar el artículo “¿Qué es el caché L2 de Hibernate?” O el artículo detallado Almacenamiento en caché en Hibernate con Redis.
fuente