2013-10-24 189 views
21

は、私は数ヶ月、今日のためにここにいます、むしろ作業コードのトンは、私がログインして次の例外を見てい:「SqlConnectionは並列トランザクションをサポートしていません」はいつ発生しますか?

System.InvalidOperationException 
SqlConnection does not support parallel transactions. 
    at System.Data.SqlClient.SqlInternalConnection.BeginSqlTransaction(
     IsolationLevel iso, String transactionName) 
    at System.Data.SqlClient.SqlConnection.BeginTransaction(
     IsolationLevel iso, String transactionName) 
    at my code here 

を、私はこの例外がスローされた理由を調査したいと思います。私はBeginTransaction()のMSDNの説明を読みましたが、それはうまく、時にはこの例外が投げられることがあると言われています。

この例外は何を意味しますか?私が探していなければならないコードの欠点は何ですか?

+0

通常のSqlConnection/SqlCommmand/SqlDataAdapterを使用していますか、またはORM(EFまたはL2Sなど)を使用していますか?明示的なトランザクションまたはTransactionScopesを使用してコードですか?また、ログに記録されている/例外をスローしているエラーの周りにコードサンプルを投稿できますか? – SimonGoldstone

+0

この回答を確認してください:http://stackoverflow.com/questions/407320/strange-sql2005-problem-sqlconnection-does-not-support-parallel-transactions これはほぼ同じ問題です。 – LawfulHacker

+0

@SimonGoldstone:私が問題を絞り込むことができるなら、私はこの質問をしません。私は「私のコードはうまくいかず、できるだけ早く助けてください」と尋ねるのではなく、自分のコードで探しているものを求めています。 – sharptooth

答えて

17

接続に既にコミットされていないトランザクションがあり、BeginTransactionを再度呼び出すと、これが表示されます。この例では

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (SqlConnection conn = new SqlConnection("Server=.;Database=TestDb;Trusted_Connection=True;")) 
     { 
      conn.Open(); 

      using (var tran = conn.BeginTransaction()) 
      { 
       using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('" + DateTime.Now.ToString() + "')", conn)) 
       { 
        cmd.Transaction = tran; 
        cmd.ExecuteNonQuery(); 
       } 

       using (var tran2 = conn.BeginTransaction()) // <-- EXCEPTION HERE 
       { 
        using (var cmd = new SqlCommand("INSERT INTO TESTTABLE (test) values ('INSIDE" + DateTime.Now.ToString() + "')", conn)) 
        { 
         cmd.Transaction = tran2; 
         cmd.ExecuteNonQuery(); 
        } 

        tran2.Commit(); 
       } 

       tran.Commit(); 
      } 
     } 
    } 
} 

...私は2番目でBeginTransactionでまったく同じ例外を取得します。

最初のトランザクションが次のトランザクションの前にコミットまたはロールバックされていることを確認してください。

ネストされたトランザクションが必要な場合は、TransactionScopeが先の方法です。

10

トランザクションに「間違った」メソッドを使用すると同じ問題が発生します。これは、新しいバージョンのEntity Frameworkにアップグレードした後に発生します。

:私たちは、SQLクエリとの取引と混合EF強い型付けされたLINQクエリを作成するには、次の方法を使用していたが、 Connectionプロパティはもう存在していなかったので、私たちは間違っていたこれ、 db.Databaseですべて db.を置き換え過去に

// previous code 
db.Connection.Open(); 
using (var transaction = db.Connection.BeginTransaction()) 
{ 
    // do stuff inside transaction 
} 
// changed to the following WRONG code 
db.Database.Connection.Open(); 
using (var transaction = db.Database.Connection.BeginTransaction()) 
{ 
    // do stuff inside transaction 
} 

どこかで彼らはEntity Frameworkの新しいバージョンでそのトランザクションメソッドの動作の動作を変更し、その溶液を使用することです:

db.Database.Connection.Open(); 
using (var transaction = db.Database.BeginTransaction()) 
{ 
    // do stuff inside transaction 
} 

お知らせtを取引がConnectionの代わりにDatabaseに呼び出されました。

+0

このソリューションは私がEFデータベースの最初のモデルを使用しているので私の問題を解決し、トランザクション内の他のテーブルへのクエリを実行するために "非トランザクション接続"を使用しました。 –

+0

私は、TransactionScopeがEF内部で本当にうまく動作することを発見しました。私は今、年齢のBeginTransactionを使用していません。私のトランザクション処理は、TransactopScopesの中で行われています。 – SimonGoldstone

+4

これを投稿していただきありがとうございます。私は全く同じ問題を抱えていた。 +1はOPの特定の状況に対する答えではないが、 – Raithlin

関連する問題