.net - title tag html
NHibernate ISession Flush: dónde y cuándo usarlo, y por qué? (4)
A partir de NHibernate 2.0, se requieren transacciones para operaciones DB. Por lo tanto, la llamada ITransaction.Commit()
manejará cualquier descarga necesaria. Si por algún motivo no está utilizando las transacciones de NHibernate, no habrá un vaciado automático de la sesión.
Una de las cosas que me confunde por completo es el uso de session.Flush
, junto con session.Commit
y session.Close
.
A veces session.Close
funciona, por ejemplo, compromete todos los cambios que necesito. Sé que necesito utilizar commit cuando tengo una transacción, o una unidad de trabajo con varias creaciones / actualizaciones / eliminaciones, para poder elegir deshacer si ocurre un error.
Pero a veces realmente me frustra la lógica detrás de la session.Flush
. session.Flush
. He visto ejemplos en los que tienes una session.SaveOrUpdate()
seguido de un color, pero cuando elimino Flush, funciona bien de todos modos. A veces me encuentro con errores en la declaración Flush diciendo que la sesión ha excedido el tiempo de espera, y eliminarla me aseguró de que no me encontré con ese error.
¿Alguien tiene una buena guía sobre dónde o cuándo usar un color? He revisado la documentación de NHibernate para esto, pero todavía no puedo encontrar una respuesta directa.
Aquí hay dos ejemplos de mi código donde fallaría sin session.Flush ():
http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html
al final de esto, puede ver una sección de código donde establezco el inserto de identidad, guardo la entidad y luego lave, luego configure el inserto de identidad. Sin esta descarga, parecía estar configurando la inserción de identidad y luego guardando la entidad.
El uso de Flush () me dio más control sobre lo que estaba pasando.
Aquí hay otro ejemplo:
Enviar mensaje NServiceBus dentro de TransactionScope
No entiendo completamente por qué en este caso, pero Flush () evitó que ocurriera mi error.
Brevemente:
- Siempre use transacciones
- No use
Close()
, en lugar de eso,ISession
sus llamadas a unaISession
dentro de una declaración deusing
o administre el ciclo de vida de su ISesión en otro lugar .
De la documentación :
ISession
,ISession
ejecutará las sentencias SQL necesarias para sincronizar el estado de la conexión ADO.NET con el estado de los objetos almacenados en la memoria. Este proceso, al ras, ocurre por defecto en los siguientes puntos
- de algunas invocaciones de
Find()
oEnumerable()
- de
NHibernate.ITransaction.Commit()
- de
ISession.Flush()
Las sentencias SQL se emiten en el siguiente orden
- todas las inserciones de entidades, en el mismo orden, los objetos correspondientes se guardaron usando
ISession.Save()
- todas las actualizaciones de la entidad
- todas las eliminaciones de colecciones
- todas las eliminaciones, actualizaciones e inserciones de elementos de colección
- todas las inserciones de colección
- todas las eliminaciones de entidades, en el mismo orden, los objetos correspondientes se eliminaron usando
ISession.Delete()
(Una excepción es que los objetos que usan la generación de ID nativa se insertan cuando se guardan).
Excepto cuando explicity
Flush()
, no hay absolutamente ninguna garantía sobre cuándo la sesión ejecuta las llamadas ADO.NET, solo el orden en que se ejecutan . Sin embargo, NHibernate garantiza que losISession.Find(..)
nunca devolverán datos obsoletos; ni devolverán los datos incorrectos.Es posible cambiar el comportamiento predeterminado para que el enjuague ocurra con menos frecuencia. La clase
FlushMode
define tres modos diferentes: solo descarga a la hora de confirmación (y solo cuando se usa NHibernateITransaction
API), enjuague automáticamente usando la rutina explicada, o nunca enjuague a menos que se llameFlush()
explícitamente. El último modo es útil para unidades de trabajo de larga ejecución, donde unaISession
se mantiene abierta y desconectada por un largo tiempo.
...
También consulte esta sección :
Terminar una sesión implica cuatro fases distintas:
- enjuagar la sesión
- comprometer la transacción
- cerrar la sesión
- manejar excepciones
Enjuagar la sesión
Si está utilizando
ITransaction
API, no necesita preocuparse por este paso. Se realizará implícitamente cuando la transacción se haya comprometido. De lo contrario, debe llamar aISession.Flush()
para asegurarse de que todos los cambios estén sincronizados con la base de datos.Commitir la transacción de la base de datos
Si está utilizando NHibernate ITransaction API, esto se ve así:
tx.Commit(); // flush the session and commit the transaction
Si administra las transacciones ADO.NET usted mismo, debe
Commit()
manualmenteCommit()
la transacción ADO.NET.
sess.Flush(); currentTransaction.Commit();
Si decide no comprometer sus cambios:
tx.Rollback(); // rollback the transaction
o:
currentTransaction.Rollback();
Si revierte la transacción, debe cerrar inmediatamente y descartar la sesión actual para asegurarse de que el estado interno de NHibernate sea coherente.
Cerrando la ISession
Una llamada a
ISession.Close()
marca el final de una sesión. La implicación principal de Close () es que la sesión renunciará a la conexión ADO.NET.
tx.Commit(); sess.Close(); sess.Flush(); currentTransaction.Commit(); sess.Close();
Si proporcionó su propia conexión,
Close()
devuelve una referencia a ella, por lo que puede cerrarla manualmente o devolverla al grupo. De lo contrario,Close()
devuelve al grupo.
Ocasionalmente, ISession ejecutará las sentencias SQL necesarias para sincronizar el estado de la conexión ADO.NET con el estado de los objetos almacenados en la memoria.
Y siempre usa
using (var transaction = session.BeginTransaction())
{
transaction.Commit();
}
después de que se hayan confirmado los cambios que esto cambia para guardarlos en la base de datos, usamos transaction.Commit ();