2016-04-11 54 views
10

nềnCác hoạt động giao dịch không thể thực hiện vì có lời đề nghị.Nhấn làm việc

Tôi có một số mã mà mở một kết nối sql, bắt đầu một giao dịch và thực hiện một số hoạt động trên DB. Mã này tạo ra một đối tượng từ DB (dequeue), lấy một số giá trị và lưu lại. Toàn bộ hoạt động cần diễn ra trong một giao dịch. Tất cả các mã hoạt động hoàn hảo mà không có giao dịch.

using (var connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 
    var transaction = connection.BeginTransaction(); 
    try 
    {      
     var myObject = foo.Dequeue(connection, transaction); 

     var url = myObj.GetFilePathUri(connection, transaction); 

     //some other code that sets object values 

     myObj.SaveMessage(connection, transaction); 
     transaction.Commit(); //error here 
    } 
    catch(Exception ex) 
    {      
     transaction.Rollback(); 
     //logging     
    } 
    finally 
    { 
     //cleanup code 
    } 
} 

phương pháp dequeue đang

public foo Dequeue(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(DEQUEUE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      ID = (Guid) reader["ID"]; 
      Name = reader["Name"].ToString(); 
      return this; 
     } 
     return null; 
    } 
} 

Nhận Đường dẫn Mã

public string GetFilePathUri(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(FILEPATH_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      return reader["Path"].ToString(); 
     } 
     return ""; 
    } 
} 

Lưu Mã

public void SaveMessage(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(SAVE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     command.Parameters.Add("@ID", SqlDbType.UniqueIdentifier).Value = ID; 
     command.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name; 
     //other object params here 
     command.ExecuteNonQuery(); 
    } 
} 

Vấn đề

Khi transaction.Commit() được gọi, tôi nhận được lỗi sau:

The transaction operation cannot be performed because there are pending requests working on this transaction.

Tôi đang làm gì sai?

EDIT: chỉnh sửa nhanh để nói rằng tôi đã đọc các câu hỏi khác về vấn đề này trên SO, nhưng không thể tìm thấy bất kỳ liên quan đến ADO.net

Trả lời

14

Tôi đã có vấn đề này trước và vấn đề đã được người đọc cần thiết phải đóng cửa. Hãy thử cách này:

public foo Dequeue(SqlConnection connection, SqlTransaction transaction) 
{ 
    using (var command = new SqlCommand(DEQUEUE_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      ID = (Guid) reader["ID"]; 
      Name = reader["Name"].ToString(); 
      reader.Close();//Closing the reader 
      return this; 
     } 
     return null; 
    } 
} 


public string GetFilePathUri(SqlConnection connection, SqlTransaction transaction) 
{ 
    string filePathUri = ""; 
    using (var command = new SqlCommand(FILEPATH_SPROC, connection) {CommandType = CommandType.StoredProcedure, Transaction = transaction}) 
    { 
     var reader = command.ExecuteReader(); 
     if (reader.HasRows) 
     { 
      reader.Read(); 
      filePathUri = reader["Path"].ToString(); 
     } 
     reader.Close();//Closing the reader 
    } 
    return filePathUri; 
} 
+0

hoạt động hoàn hảo, cảm ơn! – Jay

+1

Bạn được chào đón :). Vấn đề là chúng ta thường nghĩ rằng khi chúng ta sử dụng "sử dụng" người đọc sẽ được đóng nhưng sử dụng các giao dịch nó không được đóng lại cho đến khi bạn gọi phương thức Close(). – Ernest

+0

Khá tốt. Thực hành tốt đóng trình đọc đôi khi nó là một sai lầm phổ biến. – Robert

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