.net - ¿Cuál debería ser la duración de una sesión de NHibernate?
session lifetime (5)
Soy nuevo en NHibernate y he visto algunos problemas al cerrar sesiones prematuramente. Lo he resuelto temporalmente reutilizando sesiones en lugar de abrir una sesión por transacción. Sin embargo, tenía la impresión de que las sesiones de apertura cada vez que las necesitaban eran el enfoque recomendado para la gestión de la vida de la sesión. ¿No?
Asi que; ¿Cuál es la forma recomendada de manejar sesiones? ¿Cuál debería ser su vida? Una sesión pr transacción? ¿Una sesión única para manejar todo? ¿O que?
Editar:
Tenga en cuenta que la arquitectura de mi aplicación es una aplicación de escritorio que se comunica con un servicio del lado del servidor, que es lo que hace todo el manejo de la base de datos, utilizando NHibernate + Fluent. (Si esto hace alguna diferencia ...)
Desea una estrategia de administración de sesión que permita que su aplicación funcione de manera efectiva y aproveche las ventajas que le ofrece NHibernate, especialmente el almacenamiento en caché y la carga diferida.
Crear sesiones es un proceso económico y requiere poca RAM o CPU por adelantado, por lo que no debe preocuparse por conservar o volver a utilizar las sesiones (de hecho, volver a utilizarlas puede provocar algunos efectos secundarios desagradables y no anticipados). La fábrica de sesiones es lo más caro y debe construirse una vez y solo una vez en el inicio de la aplicación.
La regla de oro es la siguiente: la duración de la sesión debe ser lo suficientemente larga como para que no haya objetos persistentes en su alcance una vez que finalice la sesión.
Una vez que la sesión finaliza, todo el seguimiento de cambios para objetos que recibió de esa sesión se detiene, por lo que esos cambios no se guardan a menos que vuelva a adjuntar deliberadamente ese objeto a una nueva sesión. Por lo tanto, la sesión debería permanecer activa mientras existan los objetos que obtenga de ella. En una aplicación web, eso generalmente significa una sesión para cada solicitud; en WinForms, una sesión para cada formulario.
En su caso, con un servicio (supongo que se está ejecutando como un servicio de Windows) haciendo el trabajo de NHibernate, es posible que desee considerar crear una sesión para cada nueva solicitud desde la aplicación de escritorio consumidora y desecharla cuando se haya atendido esa solicitud. . Sin saber exactamente cómo se ejecuta su servicio y qué mecanismo utiliza la aplicación de escritorio para hablar con él (¿remoto? ¿WCF? ¿Llamar a SOAP?) En realidad, no puedo ser más específico.
(Hay algunas excepciones a esta regla general: supongamos que tiene un conjunto de objetos persistentes que representan un recurso compartido al que otro código se referirá pero no cambia, puede cargarlos por adelantado al inicio de la aplicación y dejarlos desconectados de ese momento) en.)
Si observa que el rendimiento es lento con dicha estrategia, es posible que solo esté hablando demasiado con la base de datos y que el gráfico de objetos sea complejo; mira el almacenamiento en caché de segundo nivel en este caso.
En una aplicación web, debe tener una sesión por solicitud. Esto le da un control total sobre la duración de la sesión y simplifica el manejo de errores.
En una aplicación de escritorio, recomiendo usar una sesión por presentador (o formulario si lo prefiere). Para citar a Ayende en su artículo de MSDN Magazine :
La práctica recomendada para las aplicaciones de escritorio es usar una sesión por formulario, de modo que cada formulario de la aplicación tenga su propia sesión. Cada formulario generalmente representa una pieza distinta de trabajo que el usuario desearía realizar, por lo que la coincidencia de la duración de la sesión con la duración de la forma funciona bastante bien en la práctica. El beneficio adicional es que ya no tiene problemas con las pérdidas de memoria, porque cuando cierra un formulario en la aplicación, también se deshace de la sesión. Esto haría que todas las entidades que fueron cargadas por la sesión sean elegibles para reclamación por el recolector de basura (GC).
Hay razones adicionales para preferir una sola sesión por formulario. Puede aprovechar el seguimiento de cambios de NHibernate, por lo que eliminará todos los cambios en la base de datos cuando realice la transacción. También crea una barrera de aislamiento entre las diferentes formas, por lo que puede enviar cambios a una sola entidad sin preocuparse por los cambios en otras entidades que se muestran en otras formas.
Gran parte del marco NHibernate y Microsoft ADO.NET Entity Framework son similares. Aquí hay un artículo muy bueno sobre cómo debe controlar una línea de vida ObjectContext en ADO.NET EF.
Debería aplicarse a las sesiones de NHibernate también.
No hay una respuesta que se adapte a todas las situaciones. La sesión 13 de Summer of Nhibernate presenta una buena visión general del problema.
Una sesión debe corresponder a una unidad de trabajo. La sesión debe permanecer activa mientras trabaja con los objetos recuperados o persistentes utilizando esa sesión.