2009-02-23 67 views
6

除了这个问题:Preorder tree traversal copy folder 我想知道是否有可能创建一个包含对数据库的不同调用的事务。在C#中的交易

例如:

public bool CopyNode(int nodeId, int parentNode) 
    { 
     // Begin transaction. 
     try 
     { 
      Method1(nodeId); 
      Method2(nodeId, parentNode); 
      Method3(nodeId); 
     } 
     catch (System.Exception ex) 
     { 
      //rollback all the methods 
     } 
    } 

我不知道这是可能的。我们使用亚音速进行数据库调用。 这非常重要,不仅是树遍历问题,还有其他一些我们所做的事情。

其主要思想是我们不能让我们的dabase受到未完成数据的破坏。

回答

3

这是可能的,你可以找到一个例子here

或许,交易范围...

http://msdn.microsoft.com/en-us/library/ms172152.aspx

+1

噢,对不起,然后,或许是交易范围会有所帮助,我从来没有与这个工作,但这里是链接: http://msdn.microsoft.com/en-us/library/ ms172152.aspx – 2009-02-23 12:23:28

1

的BeginTransaction被称为掀起了ADO.NET集合对象。 Command对象需要将此事务(SqlTransaction对象)分配给它。 提交和回滚只在外部方法中调用。

看看这段代码。它通过重新使用SqlConnection和SqlTransaction对象来工作。这是一个典型的Master> Details类型的设置。主类型是ColumnHeaderSet其中包含的

List<ColumnHeader>

一个属性,它是细节(集合)。

希望这会有所帮助。 -JM

public static int SaveColumnHeaderSet(ColumnHeaderSet set) 
     //save a ColumnHeaderSet 
     {  
     string sp = ColumnSP.usp_ColumnSet_C.ToString(); //name of sp we're using 
     SqlCommand cmd = null; 
     SqlTransaction trans = null; 
     SqlConnection conn = null; 

     try 
     { 
      conn = SavedRptDAL.GetSavedRptConn(); //get conn for the app's connString 
      cmd = new SqlCommand(sp, conn); 
      cmd.CommandType = CommandType.StoredProcedure; 
      conn.Open(); 
      trans = conn.BeginTransaction(); 
      cmd.Transaction = trans; // Includes this cmd as part of the trans 

      //parameters 
      cmd.Parameters.AddWithValue("@ColSetName", set.ColSetName); 
      cmd.Parameters.AddWithValue("@DefaultSet", 0); 
      cmd.Parameters.AddWithValue("@ID_Author", set.Author.UserID); 
      cmd.Parameters.AddWithValue("@IsAnonymous", set.IsAnonymous);   
      cmd.Parameters.AddWithValue("@ClientNum", set.Author.ClientNum); 
      cmd.Parameters.AddWithValue("@ShareLevel", set.ShareLevel); 
      cmd.Parameters.AddWithValue("@ID_Type", set.Type); 

      //add output parameter - to return new record identity 
      SqlParameter prm = new SqlParameter(); 
      prm.ParameterName = "@ID_ColSet"; 
      prm.SqlDbType = SqlDbType.Int; 
      prm.Direction = ParameterDirection.Output; 
      cmd.Parameters.Add(prm); 

      cmd.ExecuteNonQuery(); 
      int i = Int32.Parse(cmd.Parameters["@ID_ColSet"].Value.ToString()); 
      if (i == 0) throw new Exception("Failed to save ColumnHeaderSet"); 
      set.ColSetID = i; //update the object 

      //save the ColumnHeaderList (SetDetail) 
      if (ColumnHeader_Data.SaveColumnHeaderList(set, conn, trans)==false) throw new Exception("Failed to save ColumnHeaderList"); 
      trans.Commit(); 

      // return ID for new ColHdrSet 
      return i; 
     } 
     catch (Exception e){ 
      trans.Rollback(); 
      throw e; 
     } 
     finally{ 
      conn.Close(); 
     } 
     } 

public static bool SaveColumnHeaderList(ColumnHeaderSet set, SqlConnection conn, SqlTransaction trans) 
     //save a (custom)ColHeaderList for a Named ColumnHeaderSet 
     { 
     // we're going to accept a SqlTransaction to maintain transactional integrity 
     string sp = ColumnSP.usp_ColumnList_C.ToString(); //name of sp we're using 
     SqlCommand cmd = null; 
     try 
     { 
      cmd = new SqlCommand(sp, conn);  // re-using the same conection object 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Transaction = trans;   // includes the cmd in the transaction 

      //build params collection (input) 
      cmd.Parameters.Add("@ID_ColSet", SqlDbType.Int); 
      cmd.Parameters.Add("@ID_ColHeader", SqlDbType.Int); 
      cmd.Parameters.Add("@Selected", SqlDbType.Bit); 
      cmd.Parameters.Add("@Position", SqlDbType.Int); 

      //add output parameter - to return new record identity 
      //FYI - @return_value = @ID_SavedRpt 
      SqlParameter prm = new SqlParameter(); 
      prm.ParameterName = "@ID"; 
      prm.SqlDbType = SqlDbType.Int; 
      prm.Direction = ParameterDirection.Output; 
      cmd.Parameters.Add(prm); 

      //Loop 
      foreach (ColumnHeader item in set.ColHeaderList) 
      { 
       //set param values 
       cmd.Parameters["@ID_ColSet"].Value = set.ColSetID; 
       cmd.Parameters["@ID_ColHeader"].Value = item.ColHeaderID; 
       cmd.Parameters["@Selected"].Value = item.Selected; 
       cmd.Parameters["@Position"].Value = item.Position; 

       cmd.ExecuteNonQuery(); 
       int i = Int32.Parse(cmd.Parameters["@ID"].Value.ToString()); 
       if (i == 0) throw new Exception("Failed to save ColumnHeaderSet"); 
      } 
      return true; 
     } 
     catch (Exception e) 
     { 
      throw e;    
     } 

     }