2011-02-08 20 views
5

Recibo la siguiente excepción cuando uso las operaciones de Nhibernate y ADO.Net dentro de la transacción Scope.Eg. Estuvo bien con Nhibernate 2.1 pero ahora se actualizó a 3.0, lo que genera un error.Nhibernate with TransactionScope Error - Falló la fase previa de transacción de DTC - Actualizo a Nhibernate 3.0

using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
{ 
     GetmemberId(); --> NHibernate Call 
     Update(); ADO Call OracleDB 
} 

Dado que este actúa como transacción ambiente, Nhibernate trata de eliminar la transacción pronto antes de la transacción externa me completes.correct si estoy equivocado, ¿Hay alguna solución porque me ayude, pero cuando muevo la llamada Nhibernate fuera TransactionScope todo funciona bien. El ejemplo que he dado es una muestra, minas implica una más compleja, ya que tengo a mantener tanto las llamadas dentro de TransactionScope y el error Iam conseguir es la siguiente,

ERROR 13 NHibernate.Impl.AbstractSessionImpl - transacción DTC prepre phase failed System.ObjectDisposedException: no se puede acceder a un objeto eliminado. Nombre del objeto: 'Transaction'. en System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) en System.Transactions.TransactionScope.SetCurrent (Transacción newCurrent) en System.Transactions.TransactionScope.PushScope()
en System.Transactions.TransactionScope.Initialize (Transacción transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) en System.Transactions.TransactionScope..ctor (Transacción transactionToUse) en NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (PreparingEnlistment preparingEnlistment) 2011-02- 08 13: 41: 46,033 ERROR 13 NHibernate.Impl.AbstractSessionImpl - Dpreced fase de transacción DTC failed System.ObjectDisposedException: no se puede acceder a un objeto eliminado. Nombre del objeto: 'Transaction'. en System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) en System.Transactions.TransactionScope.SetCurrent (Transacción newCurrent) en System.Transactions.TransactionScope.PushScope()
en System.Transactions.TransactionScope.Initialize (Transacción transactionToUse, TimeSpan scopeTimeout, Boolean interopModeSpecified) en System.Transactions.TransactionScope..ctor (Transacción transactionToUse) en NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (preparingEnlistment preparingEnlistment)

Respuesta

6

Trate

Configuration.SetProperty(Environment.TransactionStrategy,"NHibernate.Transaction.AdoNetTransactionFactory")

O en config nhibernate

<property name="transaction.factory_class"> 
NHibernate.Transaction.AdoNetTransactionFactory 
</property> 

Funcionó para mí =)

+0

¡Gracias! ¡Funcionó para mí también! – Saxophonist

1

Nos encontramos con este mismo error, y fue causado por el camino utilizamos sesiones y transacciones en nuestra API web con NHibernate.

We debería ha estado utilizando la sesión por solicitud. (Esto puede ser una solicitud web o la ejecución de un controlador NServiceBus.) Cuando se inicia una solicitud, debe abrir una sesión e iniciar una transacción.

No estábamos haciendo eso. En nuestros repositorios, creamos una nueva sesión y transacción para cada solicitud de base de datos. Esto significaba que en lugar de tener una única sesión/transacción para una solicitud, teníamos muchas.

La causa principal del error para nosotros era que estábamos cargando una entidad (objeto de modelo de dominio) en una sesión, modificándola y guardándola con una sesión diferente. En el momento en que NHibernate ejecutó la llamada de actualización, la sesión/transacción de carga ya se había confirmado, enjuagado y cerrado.

La solución consistía en extraer nuestra creación de sesión/transacción de los repositorios y hasta la capa de Controlador (posible utilizando un HttpModule para llamadas REST y/o con programación orientada a aspectos mediante inyección de dependencia). Esta sesión/transacción entonces dura toda la vida de la llamada REST o la ejecución del controlador NServiceBus y se utiliza para todo el acceso a la base de datos durante esa llamada. Cuando la llamada finalice, se confirmará o revertirá según corresponda.

La respuesta dada anteriormente al establecer la propiedad config simplemente desactiva el DTC y revierte a la forma anterior de realizar transacciones NHibernate. Eso puede resolver el problema si nunca tiene que ampliar su API web a varias instancias, pero si lo hace, le causará problemas.

Cuestiones relacionadas