2012-03-03 20 views
9

Estoy tan confundido por las sesiones y las transacciones. Básicamente no veo cuál es el punto de tener ambas cosas, y estoy muy confundido cuando uso una u otra.Grails: ¿Cuál es la diferencia entre una sesión no eliminada y una transacción retrotraída?

¿Cuál es la diferencia entre una sesión no descargada y una transacción no confirmada?

Ni siquiera sé cómo preguntar lo que no sé ... ¿hay algún recurso que ofrezca buenos ejemplos de situaciones de sesión y transacción comunes para que pueda ver la diferencia?

Respuesta

18

Una transacción en Hibernate es más o menos lo mismo que una transacción en JDBC en general. Cuando obtiene el Connection del DataSource su valor predeterminado es autocommit = true, por lo que para la transacción que se ha cambiado a autocommit = false. De esta forma, los cambios se realizan en la base de datos solo cuando se confirman de forma explícita en lugar de cada vez que se realiza una actualización.

Hibernate Session hace varias cosas pero en este caso su función es como la memoria caché de primer nivel. Utiliza un concepto llamado "transactional writebehind" para el rendimiento para poner en cola los cambios en ese caché y solo los empuja a la base de datos cuando sea necesario. Entonces, por ejemplo, si recupera una instancia persistente y la cambia en un flujo de trabajo complejo de múltiples métodos donde cada método posiblemente no haga cambios o varios, solo se necesita una declaración SQL de actualización para que Hibernate espere hasta que sea necesario agregarlos. Sin embargo, esto es independiente de si está ejecutando una transacción, eso siempre sucede.

Donde el caché de la sesión y la transacción activa se juntan se vacían durante una transacción activa. Dado que Hibernate espera el mayor tiempo posible para eliminar los cambios, si no está en una transacción y descarga, los cambios se vuelven persistentes en la base de datos de inmediato. Entonces, esa es una optimización del rendimiento para reducir el número de escrituras en la base de datos. Pero si estás en una transacción y vacías la sesión, empujas los cambios a la base de datos. Pero la base de datos mantiene los cambios en su cola de transacciones. Por lo tanto, aunque estén en la base de datos, no estarán visibles para otras conexiones hasta que usted realice la transacción.

Idealmente, no habrá vacíos explícitos, y la confirmación de la transacción desencadenará una descarga antes de la confirmación y minimizará el número de veces que necesita ir a la base de datos y mantener los cambios no confirmados invisibles para otras personas. Pero puedes tirar tantas veces como necesites.

Una cosa que hará que Hibernate se descargue automáticamente en su nombre son las consultas. Como dije, puede realizar muchos cambios en las instancias persistentes (incluso eliminarlas) y las pondrá en cola en el caché de la sesión. Pero si ejecuta una consulta (un buscador dinámico, criterios, HQL, etc.), Hibernate no puede saber si los cambios en cola afectarán su consulta. Por lo tanto, es pesimista y se ruboriza para asegurarse de que todo sea coherente para la consulta. La base de datos usará los datos eliminados pero no confirmados para su consulta y devolverá los resultados esperados. Esta es la razón por la que recomendamos que use el método withNewSession al realizar consultas en validadores de clase de dominio personalizado para que no provoque un enrojecimiento de la sesión actual durante la validación, lo que puede causar un comportamiento extraño.

Cuestiones relacionadas