2012-03-22 2 views
1

Я видел множество примеров транзакций и в основном показываю только два примера местоположения. Если у меня есть 3 места, как мне помещать области вместе. Я пытаюсь, как показано ниже, это правильно? Другой вопрос, который я не понимаю, почему второй connectString2 должен быть под первым connectString1?Сделка транзакций для 3-х позиций

using (TransactionScope scope = new TransactionScope()) 
{ 
using (SqlConnection connection1 = new SqlConnection(connectString1)) 
{  
    using (SqlConnection connection2 = new SqlConnection(connectString2))  
    {  
    }  
    using (SqlConnection connection3 = new SqlConnection(connectString3))  
    {  
    }  
} 
} 

Настройка индивидуальной сделки

  int backUpCentralCopy = 0, backUpCentral = 0; 
      int rollbackBoolean = 0; 


      MySqlTransaction transactionLocal = null; 
      MySqlConnection connectionLocal = null; 
      transactionConnectionLocal1 callTransactionConnectionLocal1 = null; 
      try 
      { 
       callTransactionConnectionLocal1 = new transactionConnectionLocal1(); 
       connectionLocal = callTransactionConnectionLocal1.localConnection1; 
       connectionLocal.Open(); 
       transactionLocal = connectionLocal.BeginTransaction(); 
      } 
      catch (MySql.Data.MySqlClient.MySqlException ex) 
      { 
       rollbackBoolean = 1; 
       MessageBox.Show("Error From Database Connection (Local Server Is Down) " + ex.Message); 
      } 
      catch (System.Net.Sockets.SocketException ex) 
      { 
       rollbackBoolean = 1; 
       MessageBox.Show("Error Sockets From Database Connection (Local Server Is Down) " + ex.Message); 
      } 


      globalConnectionLocal1 myConnect1 = null; 
      MySqlDataReader myReader1 = null; 
      MySqlTransaction transactionCentralCopy = null; 
      MySqlConnection connectionCentralCopy = null; 
      transactionConnectionCentralCopy1 callTransactionConnectionCentralCopy1 = null; 
      try 
      { 
       myConnect1 = new globalConnectionLocal1(); 
       myConnect1.command.CommandText = "Select " + 
         "tblUpdateCentralCopy.updateCentralCopyID " + 
         "From tblUpdateCentralCopy "; 
       myReader1 = myConnect1.command.ExecuteReader(); 

       if (myReader1.HasRows == true) 
       { 
        backUpCentralCopy = 1; 
       } 
       else 
       { 
        try 
        { 
         callTransactionConnectionCentralCopy1 = new transactionConnectionCentralCopy1(); 
         connectionCentralCopy = callTransactionConnectionCentralCopy1.centralCopyConnection1; 
         connectionCentralCopy.Open(); 
         transactionCentralCopy = connectionCentralCopy.BeginTransaction(); 
        } 
        catch (MySql.Data.MySqlClient.MySqlException ex) 
        { 
         rollbackBoolean = 1; 
         backUpCentralCopy = 1; 
         MessageBox.Show("Error From Database Connection (Central C Is Down) " + ex.Message); 
        } 
        catch (System.Net.Sockets.SocketException ex) 
        { 
         rollbackBoolean = 1; 
         backUpCentralCopy = 1; 
         MessageBox.Show("Error Sockets From Database Connection (Central C Is Down) " + ex.Message); 
        } 
       } 
      } 
      catch (MySql.Data.MySqlClient.MySqlException ex) 
      { 
       rollbackBoolean = 1; 
       //backUpCentralCopy = 1; 
       MessageBox.Show("Error From UCC Check " + ex.Message); 
      } 
      catch (System.Net.Sockets.SocketException ex) 
      { 
       rollbackBoolean = 1; 
       //backUpCentralCopy = 1; 
       MessageBox.Show("Error Sockets From UCC Check " + ex.Message); 
      } 
      finally 
      { 
       myReader1.Close(); 
       myConnect1.command.Dispose(); 
       myConnect1.connection1.Close(); 
      } 

В этом разделе я читаю из сетки данных каждого значения и делать вставки и обновления операции соответственно

for (int j = 0; j < gridTransfer.RowCount; j++) 
{ 

String mySelectQuery6 = "Select tblProduct.productTotalStock, " + 
               "tblProduct.productTotalAmount, " + 
               "tblProduct.productPrice " + 
               "From tblProduct " + 
               "Where tblProduct.productID=" + Convert.ToInt32(this.gridTransfer[0, j].Value.ToString()); 

         MySqlDataReader myReader8 = null; 

         MySqlCommand myCommandLocal11 = new MySqlCommand(mySelectQuery6); 
         myCommandLocal11.Connection = connectionLocal; 

         int chTSICBefore = 0; 
         double chTAICBefore = 0.00, chACICBefore = 0.00; 

         try 
         { 
          myReader8 = myCommandLocal11.ExecuteReader(); 
          while (myReader8.Read()) 
          { 
           chTSICBefore = Convert.ToInt16(myReader8.GetValue(0).ToString()); 
           chTAICBefore = Convert.ToDouble(myReader8.GetValue(1).ToString()); 
           chACICBefore = Convert.ToDouble(myReader8.GetValue(2).ToString()); 
          } 
          if (chTSICBefore <= 0 || chTAICBefore <= 0.00 || chACICBefore <= 0.00) 
          { 
           MessageBox.Show("Error From Before chTSICBefore = " + chTSICBefore + " And chACICBefore = " + chACICBefore + " And chACICBefore = " + chACICBefore + " For pID = " + Convert.ToInt32(this.gridTransfer[0, j].Value.ToString())); 
           rollbackBoolean = 1; 
           break; 
          } 
         } 
         catch (MySql.Data.MySqlClient.MySqlException ex) 
         { 
          rollbackBoolean = 1; 
          MessageBox.Show("Error From myCommandLocal11 mySelectQuery6 " + ex.Message); 
         } 
         catch (System.Net.Sockets.SocketException ex) 
         { 
          rollbackBoolean = 1; 
          MessageBox.Show("Error Sockets From myCommandLocal11 mySelectQuery6 " + ex.Message); 
         } 
         finally 
         { 
          myReader8.Close(); 
          myCommandLocal11.Dispose(); 
         } 

         if (chTSICBefore > 0 && chTAICBefore > 0.00 && chACICBefore > 0.00) 
         { 
          String myInsertQuery3 = "Insert into tblTransferDetails " + 
              "Set transferDetailsID = " + transferDetailsID + ", " + 
              "transferID=" + transferID + ", " + 
              "outletID = " + globalSettings.settingOutletID + ", " + 
              "stockID = " + Convert.ToInt32(this.gridTransfer[3, j].Value.ToString()) + ", " + 
              "productID= " + Convert.ToInt32(this.gridTransfer[0, j].Value.ToString()) + ", " + 
              "productType = '" + this.gridTransfer[2, j].Value.ToString() + "', " + 
              "stockQuantity = 1, " + 
              "stockSIQ = '" + this.gridTransfer[10, j].Value.ToString() + "', " + 
              "costPrice = " + Convert.ToDouble(this.gridTransfer[12, j].Value.ToString()) + ", " + 
              "transferPrice = " + Convert.ToDouble(this.gridTransfer[13, j].Value.ToString()); 

          MySqlCommand myCommandLocal12 = new MySqlCommand(myInsertQuery3); 

          try 
          { 
           myCommandLocal12.Connection = connectionLocal; 
           myCommandLocal12.Transaction = transactionLocal; 
           myCommandLocal12.ExecuteNonQuery(); 
           totalCost = totalCost + Convert.ToDouble(this.gridTransfer[12, j].Value.ToString()); 
           totalTransferAmount = totalTransferAmount + Convert.ToDouble(this.gridTransfer[14, j].Value.ToString()); 

          } 
          catch (MySql.Data.MySqlClient.MySqlException ex) 
          { 
           rollbackBoolean = 1; 
           MessageBox.Show("Error From myCommandLocal12 myInsertQuery3" + ex.Message); 
          } 
          catch (System.Net.Sockets.SocketException ex) 
          { 
           rollbackBoolean = 1; 
           MessageBox.Show("Error Sockets From myCommandLocal12 myInsertQuery3" + ex.Message); 
          } 
          finally 
          { 
           myCommandLocal12.Dispose(); 
          } 

          if (backUpCentralCopy == 0) 
          { 
           MySqlCommand myCommandCentralCopy7 = new MySqlCommand(myInsertQuery3); 
           try 
           { 
            myCommandCentralCopy7.Connection = connectionCentralCopy; 
            myCommandCentralCopy7.Transaction = transactionCentralCopy; 
            myCommandCentralCopy7.ExecuteNonQuery(); 

           } 
           catch (MySql.Data.MySqlClient.MySqlException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error From myCommandCentralCopy7 myInsertQuery3" + ex.Message); 
           } 
           catch (System.Net.Sockets.SocketException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error Sockets From myCommandCentralCopy7 myInsertQuery3" + ex.Message); 
           } 
           finally 
           { 
            myCommandCentralCopy7.Dispose(); 
           } 
          } 
          else 
          { 
           String myInsertQueryReplace3 = myInsertQuery3.Replace("'", "''"); 
           MySqlCommand myCommandCentralCopy7 = new MySqlCommand("Insert into tblUpdateCentralCopy SET updateCentralCopyQuery='" + myInsertQueryReplace3 + "'"); 

           try 
           { 
            myCommandCentralCopy7.Connection = connectionLocal; 
            myCommandCentralCopy7.Transaction = transactionLocal; 
            myCommandCentralCopy7.ExecuteNonQuery(); 
           } 
           catch (MySql.Data.MySqlClient.MySqlException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error From myCommandCentralCopy7 myInsertQueryReplace3" + ex.Message); 
           } 
           catch (System.Net.Sockets.SocketException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error Sockets From myCommandCentralCopy7 myInsertQueryReplace3" + ex.Message); 
           } 
           finally 
           { 
            myCommandCentralCopy7.Dispose(); 
           } 
          } 

          if (backUpCentral == 0) 
          { 
           MySqlCommand myCommandCentral4 = new MySqlCommand(myInsertQuery3); 
           try 
           { 
            myCommandCentral4.Connection = connectionCentral; 
            myCommandCentral4.Transaction = transactionCentral; 
            myCommandCentral4.ExecuteNonQuery(); 
           } 
           catch (MySql.Data.MySqlClient.MySqlException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error From myCommandCentral4 myInsertQuery3" + ex.Message); 
           } 
           catch (System.Net.Sockets.SocketException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error Sockets From myCommandCentral4 myInsertQuery3" + ex.Message); 
           } 
           finally 
           { 
            myCommandCentral4.Dispose(); 
           } 
          } 
          else 
          { 
           String myInsertQueryReplace3 = myInsertQuery3.Replace("'", "''"); 
           MySqlCommand myCommandCentral4 = new MySqlCommand("Insert into tblUpdateCentral SET updateCentralQuery='" + myInsertQueryReplace3 + "'"); 

           try 
           { 
            //myCommandCentralDB3.CommandText = "Insert into tblUpdateCentral SET updateCentralQuery='" + myInsertQuery1 + "'"; 
            myCommandCentral4.Connection = connectionLocal; 
            myCommandCentral4.Transaction = transactionLocal; 
            myCommandCentral4.ExecuteNonQuery(); 
           } 
           catch (MySql.Data.MySqlClient.MySqlException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error From myCommandCentral4 myInsertQueryReplace3" + ex.Message); 
           } 
           catch (System.Net.Sockets.SocketException ex) 
           { 
            rollbackBoolean = 1; 
            MessageBox.Show("Error Sockets From myCommandCentral4 myInsertQueryReplace3" + ex.Message); 
           } 
           finally 
           { 
            myCommandCentral4.Dispose(); 
           } 
          } 

ответ

2

TransactionScope контекстная в настоящее время выполнение потока до его размещения. Он должен быть в вашем внешнем заявлении using (который вы правильно указали).

Соединения могут быть созданы/расположены в любом месте текущей нити до тех пор, пока область не будет удалена. Сюда входят декларации в других методах или даже в других классах и сборках.

Таким образом, вы должны обернуть свои соединения с помощью using в тех местах, где вы хотите их создать. Назначение блока using не изменяется только потому, что вы его обернули в TransactionScope.

using (TransactionScope scope = new TransactionScope()) 
{ 
    using (SqlConnection connection1 = new SqlConnection(connectString1)) 
    { 
    } 

    using (SqlConnection connection2 = new SqlConnection(connectString2))  
    {  
    } 

    using (SqlConnection connection3 = new SqlConnection(connectString3))  
    {  
    } 

    scope.Complete(); // call this otherwise the transaction will be rolled back 
} 

Обратите внимание, что вы также можете легально развернуть области (хотя это может быстро запутаться).

Если вы еще не заметили, как только вы создадите несколько подключений в пределах одной и той же области действия, транзакция будет автоматически увеличена для использования Координатора распределенных транзакций (DTC). DTC довольно легко настроить.

Многопоточные транзакции также возможны с использованием DependentTransaction.

+0

Благодарю вас за ответ. Я не понимаю вас здесь. «Цель используемого блока не меняется только потому, что вы его завернули в TransactionScope». Теперь моя следующая проблема в настоящее время у меня есть цикл for, который я читаю каждую строку datagrid, тогда я запускаю другую инструкцию insert для каждого из db. Поэтому в этом случае transactioScope мне нужно запустить один цикл for (исходный для цикла), а затем, возможно, сохранить запросы в форме массива, а затем запустить еще два цикла для другого соединения, которое это хорошая стратегия? – user837306

+0

1) Я имею в виду, что 'использование' не работает иначе, если оно находится внутри области транзакции. 2) Пока вы находитесь внутри области действия, вы должны иметь возможность выполнять свои команды в любом порядке. Тем не менее, может быть проще или быстрее создать список всех ваших операций с базой данных, а затем выполнить их в одном блоке. Если вам нужна дополнительная помощь, напишите какой-нибудь конкретный код. –

+0

Я добавил раздел 2 раздела один, я показываю, как я настраиваю отдельные транзакции. Затем в другом разделе я показываю цикл for и в том, что я запускаю индивидуальный запрос в соответствии с различными транзакциями. Так что, если мне нужно перейти к транзакции Scope, то какой из них лучше. – user837306

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