2011-02-08 11 views
5

Ricevo la seguente eccezione durante l'utilizzo delle operazioni Nhibernate e ADO.Net all'interno della transazione Scope.Eg. Stava bene con Nhibernate 2.1 ma ora aggiornato a 3.0 che genera errori.Nibire con errore TransactionScope - Fase di preparazione transazione DTC non riuscita - Aggiornamento a Nhiberno 3.0

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

Dal momento che questo comporta transazione come ambiente, NHibernate cerca di smaltire la transazione presto prima che la transazione esterna mi completes.correct se sbaglio, c'è qualche soluzione, perché mi aiuti, ma quando mi muovo la chiamata esterna NHibernate TransactionScope funziona perfettamente. L'esempio che ho dato è campione uno, miniere comporta una più complessa, dal momento che ho a mantenere sia le chiamate all'interno TransactionScope e l'errore Iam ottenere è come seguendo,

ERRORE 13 NHibernate.Impl.AbstractSessionImpl - transazione DTC fase prepre fallita System.ObjectDisposedException: impossibile accedere a un oggetto eliminato. Nome oggetto: "Transazione". a System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) a System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) a System.Transactions.TransactionScope.PushScope()
a System.Transactions.TransactionScope.Initialize (Transaction transactionToUse, TimeSpan scopeTimeout, booleano interopModeSpecified) a System.Transactions.TransactionScope..ctor (Transaction transactionToUse) a NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (PreparingEnlistment preparingEnlistment) 2011-02- 08 13: 41: 46.033 ERRORE 13 NHibernate.Impl.AbstractSessionImpl - fase di preparazione della transazione DTC non riuscita System.ObjectDisposedException: impossibile accedere a un oggetto eliminato. Nome oggetto: "Transazione". a System.Transactions.Transaction.DependentClone (DependentCloneOption cloneOption) a System.Transactions.TransactionScope.SetCurrent (Transaction newCurrent) a System.Transactions.TransactionScope.PushScope()
a System.Transactions.TransactionScope.Initialize (Transaction transactionToUse, TimeSpan scopeTimeout, booleano interopModeSpecified) a System.Transactions.TransactionScope..ctor (Transaction transactionToUse) a NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare (preparingEnlistment preparingEnlistment)

012.351.

risposta

6

Prova

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

O in config NHibernate

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

Ha funzionato per me =)

+0

Grazie! Ha funzionato anche per me! – Saxophonist

1

Ci siamo imbattuti in questo stesso errore, ed è stato causato dal modo in cui abbiamo utilizzato sessioni e transazioni nel nostro Web Api con NHibernate.

utilizza sessione per richiesta. (Può trattarsi di una richiesta Web o dell'esecuzione di un gestore NServiceBus.) Quando si avvia una richiesta, è necessario aprire una sessione e avviare una transazione.

Non lo facevamo. Nei nostri repository, abbiamo creato una nuova sessione e una nuova transazione per ogni richiesta di database. Ciò significava che, anziché avere una singola sessione/transazione per una richiesta, ne avevamo molti.

La causa principale del bug per noi era che stavamo caricando un'entità (oggetto modello dominio) in una sessione, modificandola e salvandola utilizzando una sessione diversa. Quando NHibernate ha eseguito la chiamata di aggiornamento, la sessione/transazione di caricamento era già stata impegnata, svuotata e chiusa.

La soluzione era di estrarre la nostra sessione/creazione della transazione dai repository e fino al livello Controller (eseguibile utilizzando un HttpModule per le chiamate REST e/o con la programmazione orientata all'aspetto utilizzando l'iniezione delle dipendenze). Questa sessione/transazione rimane valida per tutta la durata della chiamata REST o dell'esecuzione del gestore NServiceBus e viene utilizzata per tutto l'accesso al database durante la chiamata. Al termine di tale chiamata, verrà eseguito il commit o il rollback a seconda dei casi.

La risposta sopra indicata che imposta la proprietà config disattiva semplicemente DTC e ripristina il modo precedente di eseguire transazioni NHibernate. Questo potrebbe risolvere il problema per te se non dovessi mai scalare la tua API Web su più istanze, ma se lo fai, questo ti causerà problemi.

Problemi correlati