2012-03-22 99 views
1

我見過很多交易範圍示例,大多隻顯示2個位置示例。如果我有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循環,我讀了數據網格的每一行,然後我運行不同的插入語句爲每個數據庫。所以在這個transactioScope案例中,我必須運行一個for循環(原始for循環),然後可能將查詢存儲爲數組的形式,然後再運行另外兩個循環來進行其他連接,這是一個很好的策略? – user837306 2012-03-22 17:37:16

+0

1)我的意思是'使用'如果它在一個事務範圍內不起作用。 2)只要你在範圍內,你應該能夠以你想要的任何順序執行你的命令。但是,首先建立所有數據庫操作的列表,然後在單個塊中執行它們可能會更簡潔/更快。如果您需要更多幫助,請發佈一些特定的代碼。 – 2012-03-22 17:49:15

+0

我已經添加了2節第一節我展示瞭如何設置個人交易。然後我顯示一個for循環的另一節,並根據不同的事務運行單個查詢。所以如果我需要移動到事務範圍,那麼最好的方法是什麼。 – user837306 2012-03-23 05:07:03