2009-02-23 7 views
6

In aggiunta a questa domanda: Preorder tree traversal copy folder Mi chiedevo se è possibile creare una transazione che contiene diverse chiamate al database.Transazioni in C#

es:

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 
     } 
    } 

Non so se questo è possibile. Stiamo usando subsonic per fare le chiamate al database. Questo è molto importante, non solo per il problema di attraversamento dell'albero, ma anche per alcune altre cose che facciamo.

L'idea principale è che non possiamo permettere che la nostra dabase venga danneggiata con dati incompleti.

risposta

3

Questo è possibile, è possibile trovare un esempio here

O forse un ambito di transazione ...

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

+1

Oh scusa, allora, forse un ambito della transazione aiuterebbe, non ho mai lavorato con questo, ma ecco il link: http://msdn.microsoft.com/en-us/library/ ms172152.aspx –

1

BeginTransaction è chiamato fuori un oggetto di collezione ADO.NET. L'oggetto Comando richiede questa transazione (oggetto SqlTransaction) ad esso assegnato. Il commit e il rollback vengono chiamati solo nel metodo esterno.

Controlla questo codice. Funziona riutilizzando gli oggetti SqlConnection e SqlTransaction. Questo è un classico Master> Dettagli tipo di set up. Il tipo di master è ColumnHeaderSet che contiene una proprietà di

List<ColumnHeader>

, che è i dati (raccolta).

Spero che questo aiuti. 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;    
     } 

     }