2012-01-12 34 views
6

Tôi nhận được thông báo lỗi này khi tôi cố gắng thực thi mã sau đây.ExecuteNonQuery yêu cầu lệnh để có một giao dịch

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

Có ai có thể tư vấn vấn đề ở đâu không? Tôi đoán gốc của vấn đề là một phần mà tôi cố gắng thực hiện một thủ tục được lưu trữ.

Các thủ tục lưu trữ là tạo ra giao dịch riêng của mình khi thực hiện

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

Điểm nhỏ - bạn không nên cố gắng thực hiện 'cuối cùng' - thay vào đó, trong' try', sau khi hoạt động –

+0

có thể hơi cũ, nhưng bạn có thể vui lòng xác nhận rằng câu trả lời của tôi đã giải quyết được vấn đề của bạn? – Afshin

Trả lời

2

sử dụng Connection String giao dịch không phổ biến nên far.you có thể xóa tất cả mọi thứ có liên quan đến SqlTransaction và sau đó quấn mã của bạn với TransactionScope

+1

Hãy rất cẩn thận với TransactionScope. Nó có vẻ khá tốt đẹp khi nó hoạt động. Nhưng tôi đã tìm thấy nó rất mong manh khi nhắm mục tiêu các máy chủ SQL không cục bộ. Bạn cần mọi thứ để được thiết lập "vừa phải". –

11

khi sử dụng giao dịch, bạn nên sử dụng nó ở mọi nơi.

cmd.Transaction = transaction; 
+0

có quan trọng khi các thủ tục được lưu trữ có chứa giao dịch riêng của nó không? – pothios

+0

Trên thực tế, nó có từ quan điểm .net. – Afshin

+0

vì vậy câu hỏi là làm thế nào tôi có thể đạt được chạy một giao dịch mà sẽ gọi một thủ tục lưu trữ với giao dịch riêng của mình: ( – pothios

Các vấn đề liên quan