java - ¿Es seguro el hilo de la sesión de Hibernate?
session thread-safety (5)
El objeto Session fue diseñado para ser utilizado por un solo hilo. Internamente, la sesión utiliza muchas estructuras de datos que no son seguras para subprocesos, por lo que es imposible hacer que sean seguras para subprocesos.
Más aún, ni siquiera debería necesitar una sesión segura para subprocesos. Si su caso de uso es compartir las entidades en caché, entonces debe usar la memoria caché de segundo nivel, que es segura para subprocesos y puede usarse en un entorno agrupado.
Dicho esto, la necesidad de tener una sesión segura para subprocesos es un olor de código que indica una falla en el diseño de la capa de acceso a datos.
Necesito saber si la sesión de Hibernate es segura para subprocesos o no. Pero obviamente se adjunta una nueva sesión a cada hilo para su ejecución. Pero mi pregunta es si en un hilo he actualizado algún valor de una entidad, ¿se reflejará eso en otro hilo durante la misma ejecución?
Mi problema es cuando disparo la actualización de dos subprocesos secuencialmente, el valor se actualiza correctamente, pero cuando disparo la actualización casi en su totalidad, entonces falla.
por ej. Etapa actual de la mesa.
ID NAME MARKS
------- --------- --------
1 John 54
Estoy tratando de hacer lo siguiente:
Student student = session.load(Student.class, 1);
student.setMarks(student.getMarks() + 1);
session.update(student);
session.close();
Cuando trato de ejecutar el código anterior en el bucle, digamos 10, el valor de "marcas" en la tabla "alumno" se actualiza correctamente, es decir, el valor se actualiza a 64, lo cual es correcto.
Pero cuando intento ejecutar el mismo código en un entorno de subprocesos, da malos resultados.
No se pretende que los implementadores sean seguros para subprocesos. En su lugar, cada hilo / transacción debe obtener su propia instancia de un SessionFactory.
Incluso con esto en mente, su comportamiento podría no ser el esperado, porque las transacciones entran en juego. Tendrá que establecer un nivel de aislamiento de transacción adecuado. Consulte la guía de configuración , propiedad hibernate.connection.isolation
.
Depende de cómo estás creando una sesión.
La sesión se puede crear de dos maneras en hibernación.
- getCurrentSession ()
Sí. Ofrece seguridad para los subprocesos, ya que asegurará que creará una sesión para cada subproceso si la sesión no existe. Se adjunta a esta transacción y cierre automático de sesión.
- openSession ()
No es seguro para hilos. el desarrollador debe gestionar manualmente las transacciones y las operaciones de cierre y vaciado de sesión.
La sesión de hibernación y los hilos no se mezclan.
No debe usar una sesión de varios subprocesos a la vez, y le recomiendo que solo use una sesión de un solo subproceso. Las implementaciones de sesión de base de datos ni siquiera se requieren para ser seguras.
También debe considerar qué sucede con las transacciones cuando comienza a hacer cosas en varios subprocesos. Las transacciones están vinculadas al hilo actual. Esto se convierte rápidamente en alucinante y usted ingresa a áreas donde los implementadores no han probado sus productos.
Al final, la vida es demasiado corta para perderse en ese pantano.
Las sesiones de hibernación no son seguras para subprocesos. Use la clase TheadLocal para crear sesiones para cada hilo:
private static ThreadLocal<Session> threadSafeSession = new ThreadLocal<Session>() {
protected Session initialValue(){
return sf.openSession();
}
};
En su método, obtenga una sesión para cada hilo como:
Session session = threadSafeSession.get();