8

現在、レガシーデータアクセスコードをエンティティフレームワーク(4.3.1)に徐々に置き換えています。場合によっては、1つの作業単位で両方の方法のデータアクセスを使用することを避けられません。理想的には、これは1つのトランザクションで実行する必要があります。ただし、古いコードは、作業単位が完了し、EFが独自のトランザクションを管理するときにSqlTransaction呼び出すsを使用します。Commit()

そこで、「古い」コードと「新しい」コードをでラップすることを考えましたTransactionScope。ただし、周囲のコミットは、完了しTransactionScopeていなくても常に実行されTransactionScopeます。このコードスニペットは私の問題を示しています。

using (var conn = new SqlConnection("connection string"))
{
  conn.Open();
  using (var scope = new TransactionScope())
  {
    using (var tr = conn.BeginTransaction())
    {
      using (var cmd = conn.CreateCommand())
      {
        cmd.Transaction = tr;
        cmd.CommandText = "some update statement";
        cmd.ExecuteNonQuery();
      }
      tr.Commit();
    }
    // In reality the code above is part of a legacy DAL, immutable.
    // (can't insert SaveChanges before tr.Commit).
    context.SaveChanges();
    if (<all ok>) // pseudo code for exception handling.
        scope.Complete(); 
  }
}

がヒットされない場合でも、updateステートメントはコミットされます。scope.Complete()

TransactionScopeそのため、どうやら、古いデータアクセスコードとSaveChangesコンテキストからのを1つのトランザクションで強制的に実行するために使用することはできません。または、SqlTransaction.Commitステートメントを無効にする方法はありますか?

TransactionScopeとSqlTransactionに関する投稿が他にもあることは知っていますが、TransactionScopeを使用する場合、SqlTransactionを使用する必要はない(または推奨されない)とすべて(正しく)言っています。ただし、ここではSqlTransactionを使用しないことはできません。独自SqlTransactionのをコミットし、トランザクションメカニズムにフックするAPIを持たないレガシーフレームワークがあります。

4

1 に答える 1

9

scope.Complete()がヒットされない場合でも、updateステートメントはコミットされます。

大野!!TransacationScopeは使用されていません1

自動登録は、TransactionScopeの後で(または内部で)接続が開いている場合にのみ機能します。

Open 内部に入れると、この問題TransactionScope 修正されます(手動トランザクションでも?)。接続は[通常]アンビエントTSコンテキストに自動参加します。

既存の接続は、アンビエントトランザクションスコープに参加できますconnection.EnlistTransaction(Transaction.Current)

または、TSを既存のトランザクションから作成することもできます。たとえばnew TransactionScope(transaction)、ここで役立つ場合と役に立たない場合があります。

完全に問題がない場合は手動トランザクションを作成しますが、TS(落とし穴がわかった後!)を使用すると、トランザクションの処理がより簡単になります..少なくともほとんどの場合:)

ハッピーコーディング!


1TSは「更新ステートメント」に使用されていません。新しいcontext.SaveChanges()接続が開かれ、自動登録されるため、引き続き[可能性が高い]使用されます。

上記のいくつかのオプションを提供しましたが、単純な「ネストされた」トランザクションについてはわかりません。コンテキストで使用される(封印された?)APIを見ると、制限/制限に関するより多くの洞察が明らかになる可能性があります。

于 2012-07-10T19:22:33.183 に答える