Hibernar caché de 2nd nivel en una aplicación Grails


Parte I

En una aplicación Grails, entiendo que habilita la caché de nivel 2 por clase de dominio agregando

static mapping {
  cache true
}

De forma predeterminada, la caché de segundo nivel solo se usa cuando se llama get(), pero también se puede usar para consultas de criterios y buscadores dinámicos agregando cache true a la consulta.

Sin embargo, todavía no estoy seguro de entender cómo funciona la caché de consultas. Mi mejor conjetura es que:

  • hay cachés de consulta separados para cada clase de dominio, por ejemplo, uno para Book y otro para el autor
  • antes de ejecutar una consulta como Author.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 la caché de consulta 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, la caché de consulta de autor se vacía

Esto parece razonable hasta que consideremos que una consulta que devuelve Book las instancias pueden unirse a la tabla Author. En ese caso, sería necesario vaciar las cachés de consulta de Libro y Autor cuando se guarda, elimina o actualiza un Autor. Esto me lleva a sospechar que tal vez solo hay una caché de consulta única y se borra cada vez que se guarda cualquier clase de dominio en caché?

Parte II

En los documentos Grails se menciona que

Así como la capacidad de usar la caché de segundo nivel de Hibernate para almacenar en caché las instancias, también puede almacenar en caché colecciones (asociaciones) de objetos.

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
  }
}

¿Tiene sentido la configuración anterior, es decir, si el Autor y el libro están usando la caché de 2nd level, hay algún beneficio en hacer que la asociación Autor-Libro también use la caché de 2nd level?

Parte III

Finalmente, he leído este consejo sobre el uso de la caché de consulta de 2do nivel, que sugiere que solo debe usarse para cambiar las clases de dominio con poca frecuencia. Existir cualquier circunstancia bajo la cual uno no debería habilitar la caché de 2do nivel para operaciones get(), es decir, cualquier razón por la que uno no agregaría lo siguiente a una clase de dominio

static mapping = {
  cache true // Book uses the 2nd level cache
}
Author: Community, 2012-02-19

1 answers

Parte 1:

Hibernar hace lo correcto. La caché de consulta no es por entidad. Hay una sola región de caché de consulta, 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 caché de marcas de tiempo. Cada vez que se ejecuta una consulta, la marca de tiempo de cada una de las tablas donde la consulta busca se compara con la marca de tiempo del resultado almacenado en caché. Y, por supuesto, el resultado almacenado en caché solo se devuelve si itstimestamp es más más reciente que todas las marcas de tiempo de la tabla.

Parte 2:

Sí, tiene sentido. La 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 autor. Por lo tanto, el almacenamiento en caché de la asociación también es útil: en lugar de hacer 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 desde la caché de segundo nivel. Sin embargo, asegúrate de guardar en caché los libros.

Parte 3:

Puedo imaginar varias razones:

  • hay tantas entidades y están cambiando tanto que el número de visitas a la caché sería muy bajo, y que el manejo de la caché de segundo nivel, de hecho, consumiría más tiempo y memoria que una solución sin caché
  • la aplicación está agrupada, y el costo y la complejidad de una caché distribuida de segundo nivel es demasiado alto, para ganancia
  • otras aplicaciones no hibernadas escriben en la misma base de datos, y la caché tiene por lo tanto un gran riesgo de devolver datos obsoletos, lo que no es aceptable
  • todo va muy bien sin una caché de segundo nivel, y no hay razón para hacer que la aplicación sea más compleja de lo que es.
 43
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-21 11:04:47