hibernate - tutorial - Hibernar el segundo nivel de caché en una aplicación de Grails
que es gorm (1)
Parte 1:
Hibernate hace lo correcto. El caché de consultas no es por entidad. Existe una única región de caché de consultas, compartida por todas las consultas, a menos que establezca una región específica para una consulta. Cada vez que se actualiza una tabla, se actualiza su marca de tiempo en la memoria caché de marcas de tiempo. Cada vez que se ejecuta una consulta, la marca de tiempo de cada una de las tablas donde se busca la consulta se compara con la marca de tiempo del resultado en caché. Y, por supuesto, el resultado almacenado en caché solo se devuelve si itstimestamp es más reciente que todas las marcas de tiempo de la tabla.
Parte 2:
Sí, tiene sentido. El caché para el autor recuerda que el autor con ID 456 tiene el nombre "foo" y la fecha de nacimiento 1975/07/19. Solo se recuerdan los datos almacenados en la tabla de autor. Por lo tanto, el almacenamiento en caché de la asociación también es útil: en lugar de realizar una consulta adicional para obtener el conjunto de libros del autor al llamar a author.getBooks()
, Hibernate obtendrá los ID de los libros del autor de su caché y luego cargará cada libro del caché de segundo nivel. Sin embargo, asegúrese de guardar en caché los libros.
Parte 3:
Me puedo imaginar varias razones:
- hay tantas entidades y están cambiando que el número de visitas a la memoria caché sería muy bajo, y que el manejo del caché de segundo nivel en realidad consumiría más tiempo y memoria que una solución sin memoria caché
- la aplicación está agrupada, y el costo y la complejidad de un caché de segundo nivel distribuido es demasiado alto, para una ganancia baja
- otras aplicaciones no hibernadas escriben en la misma base de datos, y la memoria caché tiene entonces un gran riesgo de devolver datos obsoletos, lo que no es aceptable
- todo va muy bien sin un caché de segundo nivel, y no hay razón para hacer que la aplicación sea más compleja de lo que es.
Parte I
En una aplicación de Grails, entiendo que habilite el caché de segundo nivel por clase de dominio agregando
static mapping {
cache true
}
Por defecto, el segundo nivel de caché solo se usa cuando se llama a get()
, pero también se puede usar para consultas de criterios y buscadores dinámicos agregando el cache true
a la consulta.
Sin embargo, todavía no estoy seguro de entender cómo funciona el caché de consultas. Mi mejor suposición es que:
- hay cachés de consulta separados para cada clase de dominio, por ejemplo, uno para el Libro y otro para el Autor
- antes de que se
Author.findByName(''bob'', [cache: true])
una consulta comoAuthor.findByName(''bob'', [cache: true])
, se calcula una clave de caché, que se basa en la clase de dominio (Autor), la consulta (findByName) y los parámetros de consulta (''bob ''). Si esa clave se encuentra en el caché de consultas de Autor, se devuelven los resultados almacenados en caché en lugar de ejecutar la consulta - cada vez que se guarda, elimina o actualiza un autor, el caché de consulta del autor se vacía
Esto parece razonable hasta que consideremos que una consulta que devuelve instancias de libros puede unirse a la tabla Autor. En ese caso, sería necesario eliminar las cachés de consultas Libro y Autor cuando se guarda, elimina o actualiza un Autor. Esto me lleva a sospechar que tal vez solo hay un solo caché de consultas y se borra cada vez que se guarda una clase de dominio en caché.
Parte II
En los documentos de Grails, menciona que
Además de la capacidad de utilizar el caché de segundo nivel de Hibernate para almacenar en caché las instancias, también puede almacenar colecciones (asociaciones) de objetos en caché.
Por ejemplo:
class Author {
static hasMany = [books: Book]
static mapping = {
cache true // Author uses the 2nd level cache
books cache: true // associated books use the 2nd level cache
}
}
class Book {
static belongsTo = [author: Author]
static mapping = {
cache true // Book uses the 2nd level cache
}
}
¿La configuración anterior tiene sentido, es decir, si el Autor y el Libro están utilizando el caché de segundo nivel, ¿hay algún beneficio en hacer que la asociación Autor-Libro también use el caché de segundo nivel?
Parte III
Finalmente, he leído este consejo sobre el uso del caché de consultas de segundo nivel, lo que sugiere que solo se debe usar para cambiar las clases de dominio con poca frecuencia. ¿Hay alguna circunstancia en la que no se debe habilitar el caché de segundo nivel para las operaciones get()
, es decir, cualquier razón por la que no se agregue lo siguiente a una clase de dominio
static mapping = {
cache true // Book uses the 2nd level cache
}