2009-06-23 18 views
17

Estoy teniendo un gran problema tratando de resolver mis problemas de gestión de sesión en NHibernate. Estoy asumiendo que muchos de mis problemas se deben a la falta de conocimiento de los conceptos de IoC y AOP; al menos eso es en lo que estoy pensando cuando Fabio Maulo sigue dirigiéndome.Gestión de sesión de NHibernate y carga lenta

De todos modos, mi problema es que tengo una aplicación de formularios de ganar que está haciendo llamadas "get" y vincula el resultado a una grilla. Después de la vinculación, el usuario puede realizar algún tipo de acción de "escritura" y eso da como resultado que la sesión se cierre después de la escritura en un intento de utilizar la sesión por concepto de uso. Luego, el usuario puede desplazarse por la cuadrícula, lo que hace que comience la carga diferida y ahora la sesión se ha cerrado y recibo una excepción.

No quiero dejar mi opinión al tanto de mis sesiones, no quiero enviar un KillAllSessions cuando el usuario cierra el formulario. Además, un usuario puede tener múltiples formularios abiertos en cualquier momento dado que agravan aún más los problemas asociados con ese método. En esencia, quiero que todo esto funcione "detrás de escena".

Así que mi idea hasta ahora es interceptar la llamada de carga lenta y verificar si la sesión está abierta y si no la vuelvo a abrir, obtenga la información y luego vuelva a cerrarla. Sin embargo, por lo que puedo decir, que no es mucho, esto es esencialmente cómo funciona la carga diferida de todos modos. Es interceptado por la fábrica de proxy (NHibernate.Bytecode.Castle) y luego recupera los datos usando la sesión. Así que tengo que interceptar esa llamada y pasarla a la interceptación original prevista después de reabrir la sesión. Esa es mi idea.

Mi pregunta es, ante todo, ¿es esta la forma correcta de hacerlo? Segundo, si es así, ni siquiera sé por dónde empezar. Nunca he interceptado llamadas a métodos, lo sabía en teoría, pero no en la práctica. Sé que hay bibliotecas que hacen este tipo de cosas, como Rhino Commons, pero quiero aprovechar esta oportunidad para aprender y convertirme en un mejor programador. Intento entender el AOP y los Objetos del Contexto Vinculado, pero actualmente no lo estoy asimilando. ¿Podrían algunos de ustedes amigos ayudar a un chico?

+0

Suena como algo muy extraño de hacer. La sesión debe ser eliminada después de cerrar. ¿Puede dar un ejemplo? – Paco

+0

Lo siento, ¿qué parte parece extraña? En cuanto a un ejemplo, no conozco otra cosa que no sea darle la secuencia de eventos que me hizo enfrentar este problema: 1. Abra la sesión 2. Obtenga datos en forma de un IList 3. Complete una suscripción a TYyped colección 4. Vincular a la cuadrícula de datos 5. Se realiza un cambio arbitrario 6. Este cambio solicita una sesión 7. El administrador de sesiones le entrega la sesión ya abierta 8. Como es una función de escritura, cierra la sesión cuando finaliza 9. El usuario comienza a desplazarse por la grilla ocasionando que se produzca una carga diferida 10. Se produce una excepción porque la sesión ya no está abierta – joshlrogers

+0

¿Por qué se produce una carga diferida durante el desplazamiento? – Paco

Respuesta

7

puedo pensar en algunas opciones:

Opción 1: Mantener la ISession originales abierta, mientras que el usuario interactúa con los datos y cometer todos los cambios a la vez cuando se realiza el usuario. Esto significa que puede tener una gran cantidad de cambios no confirmados en la memoria y que otros usuarios no verán los cambios pendientes.

Opción 2: divide las operaciones en dos unidades de trabajo (UOW). UOW1 solo lee y es responsable de completar la lista. La ISession asociada con UOW1 permanece activa para permitir la carga diferida, como en un escenario de desglose. UOW2 es una nueva ISession efímera que se crea para las ediciones de los usuarios. Cuando se compromete una edición, el objeto original es desalojado de UOW1 y UOW1 obtiene una nueva copia de la base de datos.

Opción 3: vuelva a crear la lista después de cada edición confirmada. Esta es la solución más fácil y podría ser adecuada para pequeños conjuntos de datos.

+0

James, gracias por su respuesta, aunque tengo una pregunta. Con las opciones 1 y 2, ¿cómo cerraría la sesión después de que "get" sin la vista enviando un mensaje Kill al Session Manager diciéndole que el usuario está cerrando la aplicación o el formulario? – joshlrogers

+0

No sé lo suficiente acerca de su arquitectura para comentar. Sin embargo, parece que el límite de la unidad de trabajo sería cuando el formulario está cerrado. Creo que es mucho mejor administrar la duración de la sesión a nivel local que tener un administrador de sesión global que tenga responsabilidades más allá de la creación de nuevas sesiones. –

+0

Fui con una variante de la Opción 2: mantener la sesión de UOW1 abierta para permitir que la red se cargue lentamente mientras el usuario navega. Pero administrar sesiones individuales para hacer ediciones ha sido muy difícil. Realmente me gusta la idea de Josh de crear una sesión sobre la marcha para dar servicio a una carga lenta cada vez que se accede a los datos. –

2

Estoy trabajando en una aplicación similar. Estoy usando una sesión que mantengo abierta.

Cada vez que escribo en la base de datos utilizo begin/commit transaction que no cierra la sesión subyacente. NHibernate solo abre la conexión a la base de datos mientras la transacción está en progreso.

¿Hay algún motivo por el que deba cerrar la sesión mientras el usuario está utilizando activamente el formulario?

¿Puede proporcionar más detalles sobre lo que está utilizando para gestionar su sesión, patrón de depósito, ... etc.?

+0

Porque trato de evitar que mi vista sea consciente de mi DAL o de cualquiera de sus funciones. Mi sesión estaba siendo administrada por un patrón singleton antes de que me tocara este problema. – joshlrogers

+0

Creo mi sesión/repositorios a través de StructureMap y solo el modelo los usa. Mi punto de vista es inconsciente de la persistencia. – Maggie

+0

Tenga en cuenta que existen peligros al mantener una sesión abierta durante la vida útil de la aplicación. El rendimiento puede sufrir mucho, especialmente con las actualizaciones, si carga cientos de entidades en una sola sesión. –

Cuestiones relacionadas