2011-02-08 4 views
5

トランザクションScope.Eg内でNhibernateとADO.Net操作を使用する場合、次の例外が発生します。 Nhibernate 2.1ではうまくいきましたが、3.0にアップグレードしてエラーをスローします。TransactionScopeでNhibernateエラー - DTCトランザクション準備段階が失敗しました - Nhibernate 3.0にアップグレード

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

これは周囲のトランザクションとして機能するので、NHibernateのは、外側のトランザクションは、私が間違っている場合は、私を助けるために、すべてのソリューションがあります私をcompletes.correct前に、すぐに取引を配置しようとすると、しかし、私は外にNHibernateのコールを移動するとTransactionScopeはすべて正常に動作します。私が与えている例は、サンプル1、鉱山である私はのTransactionScope内部の両方の呼び出しを保つ必要があり、エラーはIAMは、取得には、以下の、

ERROR 13 NHibernate.Impl.AbstractSessionImplようであることから、より複雑なものを必要とする - DTCトランザクションprepre フェーズが失敗しました。System.ObjectDisposedException:破棄された オブジェクトにアクセスできません。オブジェクト名: 'トランザクション'。 System.Transactions.TransactionScope.PushScopeで System.Transactions.TransactionScope.SetCurrentで System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)(トランザクション newCurrent)()System.Transactions.TransactionScope.Initializeで
(トランザクションでSystem.Transactions.TransactionScope..ctorで transactionToUse、TimeSpanのscopeTimeout、ブールinteropModeSpecified) NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistmentで(トランザクション transactionToUse))2011-02- 08 13:41:46,033 ERROR 13 NHibernate.Impl.AbstractSessionImpl - DTCトランザクション準備フェーズ が失敗しました。System.ObjectDisposedException:破棄された オブジェクトにアクセスできません。オブジェクト名: 'トランザクション'。 System.Transactions.TransactionScope.PushScopeで System.Transactions.TransactionScope.SetCurrentで System.Transactions.Transaction.DependentClone(DependentCloneOption cloneOption)(トランザクション newCurrent)()System.Transactions.TransactionScope.Initializeで
(トランザクションで NHibernate.Transaction.AdoNetWithDistributedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(preparingEnlistment preparingEnlistment)

でSystem.Transactions.TransactionScope..ctor(トランザクション transactionToUseで transactionToUse、TimeSpanのscopeTimeout、ブールinteropModeSpecified) )

答えて

6

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

試してみてくださいまたはNHibernateの設定で

<property name="transaction.factory_class"> 
NHibernate.Transaction.AdoNetTransactionFactory 
</property> 
それは私のために働い

=)

+0

ありがとうございました!それも私のために働いた! – Saxophonist

1

私たちは、これと同じエラーに遭遇した、そしてそれは仕方によって引き起こされましたNHibernateを使用したWeb APIでセッションとトランザクションを使用しました。

はセッションごとにリクエストを使用しています。 (これは、Web要求、またはNServiceBusハンドラの実行です。)リクエストが始まると、セッションを開いてトランザクションを開始する必要があります。

私たちはそれをやっていませんでした。私たちのリポジトリでは、すべてのデータベース要求に対して新しいセッションとトランザクションを作成しました。これは、要求に対して単一のセッション/トランザクションを持つのではなく、多くを持っていたことを意味します。

バグの根本原因は、あるセッションでエンティティ(ドメインモデルオブジェクト)を読み込んで変更し、別のセッションを使用して保存していることでした。 NHibernateが更新呼び出しを実行するまでに、ロードセッション/トランザクションはすでにコミット、フラッシュ、およびクローズされていました。

解決策は、セッション/トランザクションの作成をリポジトリからコントローラレイヤまで(REST呼び出し用のHttpModuleや依存性注入を使用したアスペクト指向プログラミングで行うことができます)でした。この1つのセッション/トランザクションは、REST呼び出しまたはNServiceBusハンドラ実行の存続期間中存続し、その呼び出し中のすべてのデータベースアクセスに使用されます。コールが終了すると、適切にコミットまたはロールバックされます。

上記の設定プロパティを設定すると、単にDTCがオフになり、NHibernateトランザクションを実行する古い方法に戻ります。 Web Apiを複数のインスタンスにスケールアップする必要がない場合は、問題が解決する可能性がありますが、そうすると問題が発生します。

関連する問題