2016-03-25 2 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) 

Если это так, и где вы поставили свою точку останова, это правда, конечно, оператор вставки будет срабатывать. Причина составляет:

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

есть внутри это если инструкция. Вы говорите «если есть какие-то строки, выполните запрос вставки».

Если вы пытаетесь на самом деле получить объект 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"."); 
} 

Я, конечно, просто ухожу из предположений я изложенные выше. Если я ошибаюсь, сообщите мне.

Надеюсь, это поможет.

Смежные вопросы