NHibernate 3.0: TransactionScope y Auto-Flushing
distributed-transactions nhibernate-3 (5)
En NHibernate 3.0, FlushMode.Auto
no funciona cuando se ejecuta solo en una transacción ambiental (es decir, sin iniciar una transacción NHibernate). ¿Deberia?
using (TransactionScope scope = new TransactionScope())
{
ISession session = sessionFactory.OpenSession();
MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
session.Save(entity);
entity.Value = 30;
session.SaveOrUpdate(entity);
// This returns one entity, when it should return none
var list = session.
CreateQuery("from MappedEntity where Value = 20").
List<MappedEntity>();
}
(Ejemplo desvergonzadamente robado de esta pregunta relacionada )
En la fuente de NHibernate puedo ver que está comprobando si hay una transacción en progreso (en SessionImpl.AutoFlushIfRequired
), pero el método relevante ( SessionImpl.TransactionInProgress
) no considera las transacciones ambientales, a diferencia de su primo ConnectionManager.IsInActiveTransaction
, que sí considera las transacciones ambientales .
Buenas noticias. Gracias a Jeff Sternal (quien identificó muy bien el problema) actualicé https://nhibernate.jira.com/browse/NH-3583 y gracias al personal de NH, ya hay una solución y una solicitud de extracción, así que en la próxima versión 4.1. xx este TEMA será arreglado.
Debe usar una transacción explícita de NHibernate siempre.
using (TransactionScope scope = new TransactionScope())
using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
//Do work here
transaction.Commit();
scope.Complete();
}
Veo que también escribió en la lista de desarrolladores de NH, aunque esto puede cambiar en el futuro, así es como funciona ahora.
Para mí, no sé la razón detrás, pero al forzar el enjuague de la sesión antes de que se elimine la sesión, pareció funcionar para mí. ej. usando (sesión) {// haz tu trabajo
session.Flush (); }
Verifiqué que esto funciona con mi transacción distribuida, ya que sin hacerlo, siempre obtengo "transacción abortada" cuando se elimina TransactionScope.
Incluso fijé session.FlushMode to Commit NO funcionó para mí.
Encontré una respuesta a esto para el oráculo. Compruébelo aquí: problema de NHibernate TransactionScope con Oracle 11g
La respuesta proporcionada por Diego no funciona en el caso en que tenga una base de datos de Oracle. ( pregunta releída ). La sesión.BeginTransaction fallará porque la conexión ya es parte de una transacción.
Parece que tenemos que escribir algún código sobre este problema en nuestra aplicación (WCF, NHibernate, Oracle), pero se siente como algo que NHibernate debería proporcionar de inmediato. Entonces, si alguien tiene una buena respuesta, sería muy apreciada.