2012-04-03 13 views
7

normalmente utilizo el modelo de gestión sesión de Hibernate ThreadLocal en proyectos web en Java:Hibernate ThreadLocal ¿Administración de sesión compatible con ForkJoinPool?

El patrón Session local Tema hace uso de la clase java.lang.ThreadLocal para crear una sesión que se puede acceder desde una sola aplicación hilo. Esto es particularmente conveniente en las aplicaciones multiproceso , como las aplicaciones web.

En proyectos implemento esto con

<property name="current_session_context_class">thread</property> 

en el hibernate.xml y el uso de SessionFactory.getCurrentSession() para obtener una sesión cada vez que necesito uno.

Ahora tengo un programa que es no un Servlet, pero tiene un cómputo paralelo pesado e interacción con la base de datos.

Quiero implementar esto con un ForkJoinPool. Ahora me pregunto si es un error utilizar la gestión de sesiones de Hibernate ThreadLocal en este escenario. Por lo que yo entiendo, un ForkJoinPool utiliza una menor cantidad de subprocesos y los comparte entre las tareas en ejecución mientras otras tareas están inactivas. (Motivado por estancamiento/molesto "tarea en la transacción 'conexiones,) Quiero cerrar() cada sesión de Hibernación después de una unidad de trabajo.

Así que ... cuando llamo HibernateSessionFactory.getThreadLocalSession(). Close() en el final de mi tarea - y la tarea se ejecuta en un ForkJoinPool - surgirán problemas ¿Debo soltar el patrón ThreadLocal para los cálculos paralelos pesados ​​y gestionar las sesiones de mí mismo

Gracias de antemano por cualquier respuesta

+0

¿Está utilizando SessionFactory.getCurrentSession() o .openSession() para obtener sus objetos de sesión? Si getCurrentSession, ¿qué CurrentSessionContext estás usando? Supongo que ThreadLocalSessionContext, pero te estás refiriendo a él como un 'patrón' en contraposición a una clase. – sharakan

+0

Gracias por mirar esto ... Actualicé la pregunta con más detalle. – alfonx

Respuesta

4

Usando??. ThreadLocalSessionContext podría ser problemático para usted, pero depende de lo que estén haciendo sus tareas.

A ForkJoinPool (javadocs) está diseñado para usarlo en casos donde las tareas engendran otras tareas (el tenedor), y espera a que se completen (el join). Mientras espera, el subproceso que estaba ejecutando la tarea principal puede reutilizarse para ejecutar una tarea secundaria. De acuerdo con los javadocs para ThreadLocalSessionContext, el Session se cierra cuando compromete una transacción que obtiene de él (es decir, solo hay una transacción por cada Session).

Entonces, si tiene una tarea 'principal' que llama al sessionFactory.getCurrentSession(), y hace algunas cosas, entonces llama a commit(), la sesión se cierra y no hay peligro de interacción inapropiada.

Sin embargo, si desovar tareas de los niños después de llamar .getCurrentSession() y ANTES de llamar .commit(), es posible que encuentre a cuestiones ya otras tareas pueden ejecutarse en este tema, y ​​.getCurrentSession() devolvería la sesión utilizada por la tarea padre. Esto es casi seguro que no es lo que quiere, porque las tareas de los niños probablemente deberían estar haciendo lo mismo que las demás, y no querría que uno comparta arbitrariamente el estado Session con el padre mientras que otros no lo hacen.

Así que en resumen, usted debe:

  • No llamar session.close() si obtiene el Session de .getCurrentSession(), porque es la responsabilidad del CurrentSessionContext que lidiar con eso.
  • Manténgase en una relación de compromiso antes de tener hijos ... Quiero decir, llame al .commit() antes de generar tareas para niños.

Como nota al pie, encontré this wiki page para que me sea útil también para leer sobre el tema.

Cuestiones relacionadas