NHibernate ISession De Color:Dónde y cuándo usarlo, y por qué?
-
09-06-2019 - |
Pregunta
Una de las cosas que me confundido es el uso de session.Flush
en conjunción con session.Commit
, y session.Close
.
A veces session.Close
las obras, por ejemplo, que compromete a todos los cambios que necesito.Yo sé que tengo que usar commit cuando tengo una transacción, o una unidad de trabajo con varias crea/actualiza/se elimina, por lo que puede elegir para deshacer si se produce un error.
Pero a veces realmente me sale bloqueado por la lógica detrás de session.Flush
.He visto ejemplos donde se tiene una session.SaveOrUpdate()
seguido, pero cuando me quite el Rubor funciona bien de todos modos.A veces me encuentro con errores en la descarga declaración diciendo que la sesión se ha agotado, y la eliminación se aseguró de que no funciona en ese error.
¿Alguien tiene una buena guía para saber en donde o cuando el uso de un color?He comprobado las NHibernate documentación para esto, pero todavía no puedo encontrar una respuesta sencilla.
Solución
Brevemente:
- Siempre uso las transacciones
- No uso
Close()
, en lugar de envolver tus llamadas en unISession
en el interior de unusing
declaración o gestionar el ciclo de vida de su ISession en algún otro lugar.
De la documentación:
De vez en cuando el
ISession
se encargará de ejecutar las instrucciones SQL necesarias para sincronizar el ADO.NET relación del estado con el estado de los objetos en memoria.Este proceso, al ras, se produce de forma predeterminada en los siguientes puntos
- a partir de algunas invocaciones de
Find()
oEnumerable()
- de
NHibernate.ITransaction.Commit()
- de
ISession.Flush()
Las instrucciones SQL se expiden en el orden siguiente
- toda entidad de inserción, en el mismo orden en que los objetos correspondientes fueron salvados mediante
ISession.Save()
- de todas las entidades actualizaciones
- todos recogida de eliminaciones
- todos los de la colección de elemento eliminaciones, actualizaciones e inserciones
- todos los de la colección de inserciones
- de todas las entidades de las eliminaciones, en el mismo orden en que los objetos correspondientes, se han eliminado mediante
ISession.Delete()
(Una excepción es que los objetos utilizando el lenguaje de IDENTIFICACIÓN de la generación se insertan cuando se guardan.)
Excepto cuando expresamente
Flush()
, no hay absolutamente ninguna garantía acerca de cuando la Sesión se ejecuta el ADO.NET llamadas, sólo el orden en que se ejecutan.Sin embargo, NHibernate garantizar que laISession.Find(..)
métodos nunca volverá datos obsoletos;ni van a devolver el mal de datos.Es posible cambiar el comportamiento predeterminado para que el rubor se produce con menos frecuencia.El
FlushMode
la clase define tres modos diferentes:vaciado sólo en el momento de la confirmación (y sólo cuando el NHibernateITransaction
API se utiliza), a ras de forma automática utilizando el explicó rutina, o nunca ras, a menos queFlush()
se llama explícitamente.El último modo es útil de larga ejecución de las unidades de trabajo, donde unISession
se mantiene abierta y desconectado por un largo tiempo.
...
También se refieren a esta sección:
Terminar una sesión consta de cuatro fases bien diferenciadas:
- a ras de la sesión
- confirmar la transacción
- cierre la sesión
- el manejo de excepciones
El lavado de la Sesión
Si le sucede a ser el uso de la
ITransaction
API, usted no necesita preocuparse acerca de este paso.Se realiza de forma implícita cuando se confirma la transacción.De lo contrario, usted debe llamar aISession.Flush()
para asegurar que todos los cambios se sincronizan con la base de datos.Cometer la transacción de base de datos
Si usted está utilizando el NHibernate ITransaction API, esto se parece a:
tx.Commit(); // flush the session and commit the transaction
Si usted administra ADO.NET las transacciones de ti mismo debe manualmente
Commit()
el ADO.NET transacción.sess.Flush(); currentTransaction.Commit();
Si usted decide no confirmar los cambios:
tx.Rollback(); // rollback the transaction
o:
currentTransaction.Rollback();
Si usted deshacer la transacción debe cerrar inmediatamente y desechar la sesión actual para asegurarse de que NHibernate interna del estado es consistente.
El cierre de la ISession
Una llamada a
ISession.Close()
marca el final de una sesión.La principal implicación de Cerrar() es que el ADO.NET la conexión será cedida por el consistorio.tx.Commit(); sess.Close(); sess.Flush(); currentTransaction.Commit(); sess.Close();
Si usted proporciona su propia conexión,
Close()
devuelve una referencia a él, por lo que puede cerrar manualmente o de retorno a la piscina.De lo contrario,Close()
devuelve a la piscina.
Otros consejos
A partir de NHibernate 2.0, las transacciones son necesarios para la DB operaciones.Por lo tanto, la ITransaction.Commit()
llamada de manejar cualquier necesidad de lavado.Si por alguna razón usted no está usando NHibernate transacciones, entonces no habrá auto-lavado de la sesión.
De vez en cuando el ISession de ejecutar las instrucciones SQL necesarias para sincronizar el ADO.NET relación del estado con el estado de los objetos en memoria.
Y siempre uso
using (var transaction = session.BeginTransaction())
{
transaction.Commit();
}
después de los cambios que están comprometidos que esto cambia a guardar en la base de datos utilizamos la transacción.Commit();
Aquí hay dos ejemplos de mi código donde se iba a fallar sin sesión.Flush():
http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html
al final de este, se puede ver una sección de código donde puedo establecer la identidad de insertar en el, guarda la entidad, a continuación, vaciar, a continuación, establezca la inserción de identidad off.Sin este color parecía ser la configuración de la identidad insertar en y fuera de ahorro de la entidad.
El uso de Flush() me dio más control sobre lo que estaba pasando.
Aquí está otro ejemplo:
El envío de NServiceBus mensaje dentro de TransactionScope
No entiendo por qué en esto, pero Flush() impidió que mi error ocurra.