2011-11-15 24 views
9

Tôi có điều này trong một lớp có tên là "MessageQueueReceive".MSMQ nhận được với giao dịch - rollback không làm cho thông báo có sẵn trở lại

public MessageQueueTransaction BlockingReceive(out Message message) 
{ 
    MessageQueueTransaction tran = null; 
    message = null; 

    tran = new MessageQueueTransaction(); 

    tran.Begin(); 
    try 
    { 
     message = Queue.Receive(new TimeSpan(0, 0, 5), tran); 
    } 
    catch (MessageQueueException ex) 
    { 
     // If the exception was a timeout, then just continue 
     // otherwise re-raise it. 
     if (ex.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout) 
      throw ex; 
    } 

    return tran; 

} 

Sau đó, vòng lặp xử lý của tôi có này: -

while (!Abort) 
{ 
    try 
    { 
     tran = this.Queue.BlockingReceive(out msg); 

     if (msg != null) 
     { 
      // Process message here 

      if (tran != null) 
       tran.Commit(); 
     } 
    } 
    catch (Exception ex) 
    { 
     if (tran != null) 
      tran.Abort(); 

    } 
} 

Việc kiểm soát công cụ bảng cho thấy hàng đợi thông điệp mà tôi đang sử dụng là giao dịch. Hàng đợi tạp chí không được bật.

Mã này tạo ra hàng đợi: -

private static MessageQueue CreateMessageQueue(string queueName, bool transactional = false) 
{ 
    MessageQueue messageQueue = MessageQueue.Create(queueName, transactional); 
    messageQueue.SetPermissions("Administrators", MessageQueueAccessRights.FullControl, 
      AccessControlEntryType.Allow); 
    return messageQueue; 
} 

Tham số giao dịch được thiết lập là "true" khi điều này được gọi.

Điều tôi thấy là khi ngoại lệ xảy ra trong quá trình xử lý thư, tran.Abort được gọi nhưng tại thời điểm đó, tôi muốn thư được trả về hàng đợi. Tuy nhiên, điều này không xảy ra và các tin nhắn bị mất.

Tôi có thiếu thứ gì đó hiển nhiên không? Ai có thể nhìn thấy những gì tôi đang làm sai?

+0

Hàng đợi bạn đang nhận trên máy cục bộ với dịch vụ người nghe phải không? –

+0

Có, quá trình gửi và nhận và hàng đợi là tất cả trên cùng một hộp. Chúng là hàng đợi riêng tư. Tôi cũng có cùng mã chạy trên một vài hộp khác nhau và thấy cùng một vấn đề.Điều đó cho thấy nó liên quan đến mã này chứ không phải là một cái gì đó kỳ quặc về máy. – JohnCC

+0

Câu hỏi rõ ràng tôi đoán. Bạn có chắc chắn nó đang nhấn ngoại lệ với việc hủy bỏ trong? Có thể là một ngoại lệ được ném trong mã xử lý tin nhắn của bạn bị bắt và sau đó bị vứt đi để nó không bao giờ bong bóng cho bạn xử lý ngoại lệ với việc hủy bỏ trong đó? –

Trả lời

5

Cảm ơn tất cả các nhận xét. Tôi đã tổ chức lại mã của tôi như Russell McClure đề nghị, và tôi đã cố gắng để tạo ra các trường hợp thử nghiệm đơn giản nhưng không thể tái tạo vấn đề.

Cuối cùng, vấn đề không phải là tất cả những gì tôi đang tìm kiếm (tần suất xảy ra như thế nào?).

Trong đường dẫn của tôi, tôi đã có một trình kiểm tra tin nhắn trùng lặp. "Thông điệp" mà hệ thống của tôi đề cập đến là từ các thiết bị từ xa trên mạng WAN và đôi khi các thông báo trên dây bị sao chép.

Khi thư được kéo từ MSMQ, thư sẽ được chuyển qua trình kiểm tra trùng lặp của trình ghi cơ sở dữ liệu. Nếu người viết cơ sở dữ liệu không thành công, kiểm tra trùng lặp đã không loại bỏ băm từ bảng của nó. Khi quá trình thử lặp lại, nó sẽ nhận được thông báo tương tự từ hàng đợi vì giao dịch MSMQ đã được khôi phục khi trình ghi cơ sở dữ liệu thất bại. Tuy nhiên, trong lần thử thứ hai, người kiểm tra trùng lặp sẽ phát hiện ra rằng nó đã nhìn thấy tin nhắn trước đó và nuốt nó một cách im lặng.

Khắc phục là làm cho người kiểm tra trùng lặp phát hiện ngoại lệ đến từ liên kết tiếp theo trong chuỗi và quay lại bất kỳ điều gì mà nó đã làm.

1

Hàng đợi của bạn cần phải được tạo thành hàng đợi giao dịch để có được những gì bạn muốn.

enter image description here

EDIT:

Vâng, nếu hàng đợi của bạn là giao dịch sau đó trỏ đến một thực tế rằng bạn đang xử lý sai giao dịch của bạn, mặc dù tôi không thể nhìn thấy cụ thể cách nó đang xảy ra. Tôi sẽ thay đổi phương thức BlockingReceive của bạn để trả lại tin nhắn. Tôi sẽ di chuyển việc tạo MessageQueueTransaction sang phương thức bên ngoài. Mã của bạn sẽ được duy trì nhiều hơn nếu bạn có các lệnh gọi Begin, Commit và Abort trong cùng một phương thức.

+0

Xin chào! Hàng đợi chắc chắn được tạo thành hàng đợi giao dịch. Nếu tôi nhìn vào các thuộc tính hàng đợi trong Computer Management-> Services và Applications -> Message Queuing, nó hiển thị như là transactional. – JohnCC

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