2012-03-22 71 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