2016-03-25 8 views
0

以下の挿入と削除の両方が完全に動作するかどうかを確認しようとしています。私は私のトランザクションスコープの外に私の接続オブジェクトを持っていると私は100%確かではないと確信しています。TransactionScopeが正常に動作していないと思われる

私はこのコードが意図したとおりに機能していないことを知っています。最初の部分(挿入が実行された後)が終了し、ブレークポイントで終了すると、実際にはscope.completeを呼び出さなくても行が挿入されます。

私の考え方とロジックの欠陥をここで指摘してください。

   sqlConnection.Open(); 

       int numFound = 1; 
       int max = 99; 
       int iteration = 0; 
       while (iteration < max && numFound > 0) 
       { 
        iteration++; 
        var ids = new List<int>(); 
        using (var sqlCommand0 = new SqlCommand(sql0, sqlConnection)) 
        { 
         using (SqlDataReader reader1 = sqlCommand0.ExecuteReader()) 
         { 
          while (reader1.Read()) 
          { 
           ids.Add(reader1.GetInt32(0)); 
          } 
         } 
        } 
        numFound = ids.Count; 
        if (numFound > 0) 
        { 
         using (var scope = new TransactionScope()) 
         { 
          string whereClause = $"WHERE Id IN ({string.Join(",", ids)})"; 

          string sql1 = string.Format(sqlTemplate1, whereClause); 
          using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection)) 
          { 
           sqlCommand1.ExecuteNonQuery(); 
          } 

          // BREAK POINT HERE - ABORTED PROGRAM AND sql1 had been committed. 

          var sql2 = "DELETE FROM SendGridEventRaw " + whereClause; 
          using (var sqlCommand2 = new SqlCommand(sql2, sqlConnection)) 
          { 
           sqlCommand2.ExecuteNonQuery(); 
          } 
          scope.Complete(); 
          total += numFound; 
          Console.WriteLine("deleted: " + whereClause); 
         } 
        } 
       } 
      } 

答えて

3

私は、トランザクションを開始する前に接続を開いていると思います。まず、トランザクションを開始して接続を開くことで問題を解決できます。あなたの最初のクエリがいくつかのレコードを取得する場合は、次のクエリは、したがって、文を実行 :ちょうど私が見ていたものとし、私が想定していますが、あなたが起こるしようとするものですから

0

はこれです

if (numFound > 0) 

これが当てはまり、ブレークポイントを置く場所が真の場合、もちろんinsert文が起動します。理由:

using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection)) 
          { 
           sqlCommand1.ExecuteNonQuery(); 
          } 

はif文内にあります。 「行がある場合は、挿入クエリを実行してください」と言っています。

実際にscopeオブジェクトにクエリを実行させる場合は、オブジェクト内ですべてのクエリ構築が行われてから、実行がscope.complete()になる必要があります。例えば

//In TransactionScope class 

public string Complete(var ids, int numFound, SqlConnection sqlConnection, string sqlTemplate1) 
{ 
    string whereClause = $"WHERE Id IN ({string.Join(",", ids)})"; 

          string sql1 = string.Format(sqlTemplate1, whereClause); 
          using (var sqlCommand1 = new SqlCommand(sql1, sqlConnection)) 
          { 
           sqlCommand1.ExecuteNonQuery(); 
          } 

          var sql2 = "DELETE FROM SendGridEventRaw " + whereClause; 
          using (var sqlCommand2 = new SqlCommand(sql2, sqlConnection)) 
          { 
           sqlCommand2.ExecuteNonQuery(); 
          } 
          return whereClause; 
} 


//in your Main class 

if (num > 0) 
{ 
    string whereClause = scope.Complete(ids, numFound, sqlConnection, sqlTemplate1); 
    Console.WriteLine("deleted" + whereClause"."); 
} 

は、私はもちろん、私は上記の仮定のオフつもりです。私が間違っている場合は、私に知らせてください。

希望します。

関連する問題