2012-01-12 23 views
6

Ricevo questo messaggio di errore quando provo a eseguire il seguente codice.ExecuteNonQuery richiede che il comando abbia una transazione

ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction 

Qualcuno può chiedere dove si trova il problema? Immagino che la radice del problema sia la parte in cui provo ad eseguire una stored procedure.

La stored procedure è crea la propria transazione quando eseguire

using (SqlConnection conn = new SqlConnection(connStr)) 
      { 
       conn.Open(); 

       SqlCommand command = conn.CreateCommand(); 
       SqlTransaction transaction; 

       // Start a local transaction. 
       transaction = conn.BeginTransaction("createOrder"); 

       // Must assign both transaction object and connection 
       // to Command object for a pending local transaction 
       command.Connection = conn; 
       command.Transaction = transaction; 

       try 
       { 
        command.CommandText = "INSERT INTO rand_resupply_order (study_id, centre_id, date_created, created_by) " + 
         "VALUES (@study_id, @centre_id, @date_created, @created_by) SET @order_id = SCOPE_IDENTITY()"; 

        command.Parameters.Add("@study_id", SqlDbType.Int).Value = study_id; 
        command.Parameters.Add("@centre_id", SqlDbType.Int).Value = centre_id; 
        command.Parameters.Add("@date_created", SqlDbType.DateTime).Value = DateTime.Now; 
        command.Parameters.Add("@created_by", SqlDbType.VarChar).Value = username; 

        SqlParameter order_id = new SqlParameter("@order_id", SqlDbType.Int); 
        //study_name.Value = 
        order_id.Direction = ParameterDirection.Output; 
        command.Parameters.Add(order_id); 

        command.ExecuteNonQuery(); 
        command.Parameters.Clear(); 

        //loop resupply list 
        for (int i = 0; i < resupplyList.Count(); i++) 
        { 
         try 
         { 
          SqlCommand cmd = new SqlCommand("CreateOrder", conn); 
          cmd.CommandType = CommandType.StoredProcedure; 

          cmd.Parameters.Add("@study_id", SqlDbType.Int).Value = study_id; 
          cmd.Parameters.Add("@centre_id", SqlDbType.Int).Value = centre_id; 
          cmd.Parameters.Add("@created_by", SqlDbType.VarChar).Value = username; 
          cmd.Parameters.Add("@quantity", SqlDbType.VarChar).Value = resupplyList[i].Quantity; 
          cmd.Parameters.Add("@centre_id", SqlDbType.Int).Value = centre_id; 
          cmd.Parameters.Add("@depot_id", SqlDbType.VarChar).Value = depot_id; 
          cmd.Parameters.Add("@treatment_code", SqlDbType.Int).Value = centre_id; 
          cmd.Parameters.Add("@order_id", SqlDbType.Int).Value = (int)order_id.Value; 
          cmd.ExecuteNonQuery(); 
         } 
         catch (SqlException ex) 
         { 
          transaction.Rollback(); 
          ExceptionUtility.LogException(ex, "error"); 
          throw ex; 
         } 
         catch (Exception ex) 
         { 
          transaction.Rollback(); 
          ExceptionUtility.LogException(ex, "error"); 
          throw ex; 
         } 
         finally 
         { 
          conn.Close(); 
          conn.Dispose(); 
         } 

        } 

        return (int)order_id.Value; 

       } 
       catch (Exception ex) 
       { 
        transaction.Rollback(); 
        ExceptionUtility.LogException(ex, "error"); 
        throw ex; 
       } 
       finally 
       { 
        // Attempt to commit the transaction. 
        transaction.Commit(); 

        conn.Close(); 
        conn.Dispose(); 
        command.Dispose(); 
       } 
+0

Punto minore - non si dovrebbe cercare di impegnarsi in 'finally' - che dovrebbe, invece, essere in' try', dopo l'operazione –

+0

potrebbe essere un po 'vecchio, ma si può confermare che la mia risposta ha risolto il tuo problema? – Afshin

risposta

2

utilizzando Connessione transazione stringa non popolare in modo far.you possibile eliminare ogni cose che si sono riferiti a SqlTransaction e poi avvolgere il codice con TransactionScope

+1

Fai molta attenzione con TransactionScope. Sembra piuttosto carino quando funziona. Ma ho trovato molto fragile quando si tratta di server SQL non locali. Hai bisogno di cose da configurare "giusto". –

11

quando usi la transazione, dovresti usarla ovunque.

cmd.Transaction = transaction; 
+0

importa quando le stored procedure contengono la propria transazione? – pothios

+0

In realtà sì da .net punto di vista. – Afshin

+0

quindi la domanda è come posso ottenere l'esecuzione di una transazione che chiamerà una stored procedure con una propria transazione :( – pothios

Problemi correlati