1

何かをデバッグしようとすると、次のことを効果的に実行しているコードが見つかりました。

  1. トランザクション スコープの作成
  2. トランザクションの作成 (この場合は nHibernate tx ですが、あまり重要ではありません)
  3. 2 番目のトランザクション (この場合は標準の ADO.Net Tx) の作成
  4. 2 番目のトランザクションのコミット
  5. Transaction スコープで Complete() を呼び出す
  6. トランザクション スコープの破棄。

現在 - トランザクションを作成してコミットしないというのは、おそらくとにかく悪い考えです。

ただし、これをテストするとき-上記のさまざまな組み合わせを試しました(すべてのトランザクションをコミットする、いくつかのトランザクションをコミットする、トランザクションなし(つまりTScopeのみ)、最初をコミットするが2番目はコミットしない、他のトランザクションを追加するなど)すべてのテストで、次のことがわかりました本当だ:

最初のトランザクションのコミットに失敗し、トランザクション スコープが分散された場合にのみ、TScope の Dispose は次のエラーで失敗します。

System.InvalidOperationException : 操作は、登録の現在の状態に対して有効ではありません。

私は今興味があり、なぜこれが事実なのか知りたいですか?

4

1 に答える 1

1

あなたが見ている問題は、次のいずれかでカバーされていると思われます:

何が起こるかは完全にはわかりませんが、同様の動作を見てきました。たとえば、NH がアンビエント トランザクションに参加し、トランザクションが後で分散された場合、TransactionScope.Complete() の呼び出しが 20 秒間ハングしてから失敗する可能性があります。

NH トランザクションを使用しない場合でも、NH は TransactionScope に登録しようとします。この場合、NH はアンビエント トランザクションの Prepare() フェーズ中に変更をフラッシュします。これは db 接続で実行されますが、これもトランザクションに参加しており、独自の Prepare() 呼び出しを取得します。残念ながら、正確な問題を突き止めることはできませんでしたが、状況によっては、NHibernate の Prepare() の前に db 接続の Prepare() が呼び出されるのではないかと思います。後者は db 接続を使用し続けようとしますが、これにより何らかのデッドロックが発生するようです。

NH トランザクションを使用し、トランザクション スコープを完了する前にこれをコミットすると、基礎となる DB 接続が準備フェーズに入る前に、NH がその変更をフラッシュします。

于 2012-11-15T22:54:16.147 に答える