2012-02-10 24 views
13

Tôi có một ứng dụng web mùa xuân chạy trên jboss hiện được định cấu hình để sử dụng HibernateTransactionManager cho các giao dịch db và JmsTransactionManager cho jms. Đối với jms, chúng tôi sử dụng Camel và ActiveMQ, cơ sở dữ liệu của chúng tôi là DB2. Trong một giao dịch, tôi cần viết một số bản ghi vào cơ sở dữ liệu và gửi hai tin nhắn jms không đồng bộ. Các tin nhắn jms là thông báo sự kiện và tôi chỉ muốn chúng được gửi nếu giao dịch cơ sở dữ liệu cam kết.Đồng bộ hóa giao dịch mùa xuân của JDBC và JMS

Tôi sẵn sàng chấp nhận rủi ro giao tiếp với nhà môi giới thất bại sau khi giao dịch jdbc đã cam kết (và do đó không có thư nào được gửi nhưng db cam kết) vì vậy tôi không nghĩ rằng tôi cần XA thích hợp.

Tôi tin rằng những gì tôi cần là quản lý giao dịch "nỗ lực tốt nhất" bằng cách sử dụng đồng bộ hóa giao dịch mùa xuân.

Tài liệu hướng dẫn mùa xuân gợi ý thực tế là mùa xuân sẽ đồng bộ hóa hai giao dịch và cam kết giao dịch jms chỉ sau khi giao dịch jdbc đã được cam kết - nhưng tôi không nghĩ nó rất rõ ràng. Tài liệu hướng dẫn mùa xuân ở đây http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-resource-synchronization không đi vào chi tiết đầy đủ về cách hoạt động của tài liệu.

Tôi đã tìm thấy một vài nguồn khác nói rằng mùa xuân sẽ làm những gì tôi muốn bao gồm một số javadoc dưới đây, và tôi đã viết một số bài kiểm tra tích hợp cũng hiển thị nó.

http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted%28boolean%29 javadoc trên setSessionTransacted ở đây có vẻ giống như chính xác những gì tôi muốn.

Từ những gì tôi đã thấy Tôi nghĩ rằng tạo Camel JmsConfiguration với giao dịch thiết lập là true như thế này là đủ:

<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> 
    <property name="connectionFactory" ref="pooledConnectionFactory"/> 
    <property name="transacted" value="true"/> 
    <property name="concurrentConsumers" value="10"/> 
</bean> 

Tuy nhiên tôi cần phải thuyết phục một người nào đó tôi làm việc với ai là một chút hoài nghi và cho rằng tôi kiểm thử tích hợp chỉ hoạt động vì tác dụng phụ kém tài liệu hơn là tính năng mùa xuân có chủ ý. Vì vậy, câu hỏi của tôi là - Tôi có chính xác rằng mùa xuân có thể được dựa vào để đồng bộ hóa các giao dịch và luôn cam kết giao dịch jms sau giao dịch jdbc hay không phải cái gì mà tôi nên dựa vào, và bạn có thể chỉ cho tôi bất kỳ tài liệu chính thức nói rõ ràng? Và tôi đoán nói chung là một cách tiếp cận tốt để có hoặc chúng ta nên quản lý các giao dịch này theo một cách khác?

+0

Xin chào, bạn có câu trả lời cho câu hỏi của mình ngay bây giờ không? – snowindy

+0

Xin chào, không thực sự. Tôi vẫn chưa thấy bất kỳ tài liệu thực sự rõ ràng đó là những gì tôi muốn nhưng chúng tôi đang sử dụng nó trong sản xuất mà không có bất kỳ vấn đề. – laurie

Trả lời

3

Bài viết này có thể trợ giúp Distributed transactions in Spring, with and without XA. Tôi không nghĩ rằng nó bao gồm trường hợp của bạn cụ thể - gửi tin nhắn + cập nhật cơ sở dữ liệu.

+0

Cảm ơn, tôi đã đọc bài viết đó một vài lần.Trong phần nỗ lực tốt nhất, họ cung cấp hai ví dụ về đồng bộ hóa mùa xuân, nhưng trong một cấu hình, chúng cấu hình một TransactionAwareConnectionFactoryProxy và trong một ChainedTransactionManager khác. Nếu tôi không cần phải làm bất kỳ cấu hình bổ sung để có được kết quả tương tự thì tôi không muốn. – laurie

0

Nếu bạn đang sử dụng các giao dịch địa phương Và usecase là tiết kiệm tới cơ sở dữ liệu và sau đó gửi tới JMS

Sau đó, có thể có ba trường hợp:

  1. ngoại lệ chỉ sau khi nhận được (trước khi DB và JMS)

Không có vấn đề tất cả mọi thứ sẽ được rolledback

  1. Sau khi lưu vào DB, chúng tôi có ngoại lệ

Nếu có một hoạt động chèn, sẽ có mutiple hàng trong DB do retries.With mỗi thử lại, một chèn sẽ done.And cho JMS, thư sẽ chuyển đến DeadLetterQueue

  1. Sau khi lưu vào DB và gửi đến JMS, chúng tôi có một ngoại lệ

    Nếu có một hoạt động chèn, sẽ có mutiple hàng trong DB do retries.With mỗi thử lại, một chèn sẽ được thực hiện. và đối với JMS, thư sẽ chuyển đến DeadLetterQueue

Bây giờ bạn không muốn sử dụng XA, vì vậy các giải pháp có thể là

1) Kiểm tra Nếu (mớ hỗn độn age.getJmsRedelivered() {...}

Nếu không, quá trình nó

Nếu redelivered của nó, kiểm tra xem bạn xử lý nó đã

Kiểm tra nếu các dữ liệu có trong mạng dựa trên các chi tiết trong thông điệp

Lưu ý rằng tái giao hàng là rất hiếm như vậy, việc kiểm tra này cũng rất hiếm và không có chi phí

2) Nếu phương pháp của bạn là idempotent, sau đó bạn không cần phải kiểm tra này

Và về XA, XA đảm bảo thông điệp mà được phân phối duy nhất một lần Và đồng bộ hóa các giao dịch trên nhiều nguồn lực

Nhưng với XA, bạn có overhead

Vì vậy, nếu bạn có thể quản lý mà không XA, nó là một lợi thế

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