2011-09-09 12 views
6

Tôi có trường hợp sử dụng này.Tích hợp mùa xuân: khó khăn với giao dịch giữa 2 người kích hoạt

chuỗi đầu tiên:

<int:chain input-channel="inserimentoCanaleActivate" output-channel="inserimentoCanalePreRouting">  
    <int:service-activator ref="inserimentoCanaleActivator" method="activate" />     
</int:chain> 

Đây là mã tương đối:

@Override 
@Transactional(propagation = Propagation.REQUIRES_NEW) 
public EventMessage<ModificaOperativitaRapporto> activate(EventMessage<InserimentoCanale> eventMessage) { 
    ... 
    // some Database changes 
    dao.save(myObject); 
} 

Tất cả đang làm việc tuyệt vời.

Sau đó, tôi có một chuỗi:

<int:chain id="onlineCensimentoClienteChain" input-channel="ONLINE_CENSIMENTO_CLIENTE" output-channel="inserimentoCanaleActivate"> 
    <int:service-activator ref="onlineCensimentoClienteActivator" method="activate" /> 
    <int:splitter expression="payload.getPayload().getCanali()" /> 
</int:chain> 

Và activator tương đối:

@Override 
public EventMessage<CensimentoCliente> activate(EventMessage<CensimentoCliente> eventMessage) { 
    ... 
    // some Database changes 
    dao.save(myObject); 
} 

Các CensimentoCliente tải trọng như mô tả dưới đây có List của tải trọng của chuỗi đầu tiên, vì vậy với một splitter tôi chia nhỏ trong danh sách và sử dụng lại mã của chuỗi đầu tiên.

public interface CensimentoCliente extends Serializable { 

    Collection<? extends InserimentoCanale> getCanali(); 

    void setCanali(Collection<? extends InserimentoCanale> canali); 
    ... 
} 

Nhưng vì mọi người kích hoạt đều có định nghĩa giao dịch của anh ấy (vì người đầu tiên có thể sống mà không có người thứ hai) Tôi có trường hợp sử dụng khi giao dịch được tách ra.

Mục đích là để có db sửa đổi của hai chuỗi là một phần của cùng một giao dịch.

Bất kỳ trợ giúp nào?

Kind coi Massimo

+0

Bạn đã bao giờ tìm thấy một giải pháp? – dMcNavish

+0

Không ........... –

Trả lời

0

Là những sửa đổi 2 cơ sở dữ liệu quan hệ riêng biệt? Nếu vậy bạn đang xem xét một giao dịch XA. Bây giờ nếu bạn đang chạy nó trên một thùng chứa XA không giống như tomcat, tất cả điều này phải được thực hiện trong một luồng đơn được người quản lý giao dịch xem (bạn sẽ phải quay lại trình quản lý giao dịch thực sự kích hoạt các sự kiện này). Người quản lý giao dịch có thể là một tin nhắn JMS hoặc một poller đối với một số nguồn dữ liệu. Ngoài ra, quá trình xử lý này phải được thực hiện trong một luồng đơn để lò xo có thể giúp bạn chạy toàn bộ quy trình trong một giao dịch duy nhất.

Lưu ý cuối cùng, không giới thiệu luồng/hàng đợi giữa các trình kích hoạt dịch vụ. Điều này có thể gây ra các chất hoạt hoá để chạy trên những luồng riêng

3

Bạn có thể thực hiện điều này bằng cách tạo ra một kênh tùy chỉnh (hoặc một thành phần tùy chỉnh khác, nhưng đây là cách tiếp cận đơn giản nhất) mà kết thúc tốt đẹp các công văn thông điệp trong một thực TransactionTemplate callback:

public class TransactionalChannel extends AbstractSubscribableChannel { 

    private final MessageDispatcher dispatcher = new UnicastingDispatcher(); 
    private final TransactionTemplate transactionTemplate; 

    TransactionalChannel(TransactionTemplate transactionTemplate) { 
     this.transactionTemplate = transactionTemplate; 
    } 

    @Override 
    protected boolean doSend(final Message<?> message, long timeout) { 
     return transactionTemplate.execute(new TransactionCallback<Boolean>() { 
      @Override 
      public Boolean doInTransaction(TransactionStatus status) { 
       return getDispatcher().dispatch(message); 
      } 
     }); 
    } 

    @Override 
    protected MessageDispatcher getDispatcher() { 
     return dispatcher; 
    } 

} 

Trong XML, bạn có thể xác định kênh và giao dịch của bạn mẫu và tham khảo kênh tùy chỉnh của bạn cũng giống như bạn sẽ bất kỳ kênh khác:

<bean id="transactionalChannel" class="com.stackoverflow.TransactionalChannel"> 
     <constructor-arg> 
      <bean class="org.springframework.transaction.support.TransactionTemplate"> 
       <property name="transactionManager" ref="transactionManager"/> 
       <property name="propagationBehavior" value="#{T(org.springframework.transaction.TransactionDefinition).PROPAGATION_REQUIRES_NEW}"/> 
      </bean> 
     </constructor-arg> 
    </bean> 

Ví dụ, bạn có lẽ có thể sử dụng một cây cầu để vượt qua t anh nhắn qua kênh mới:

<int:bridge input-channel="inserimentoCanaleActivate" output-channel="transactionalChannel" /> 
<int:chain input-channel="transactionalChannel" output-channel="inserimentoCanalePreRouting">  
    <int:service-activator ref="inserimentoCanaleActivator" method="activate" />     
</int:chain> 
2

Bạn bạn có <service-activator>@Transactional về phương pháp dịch vụ, giao dịch sẽ được bao bọc chỉ với phương pháp gọi. Nếu bạn muốn chuyển tải toàn bộ luồng tin nhắn (hoặc phần của nó), bạn nên khai báo lời khuyên TX ở đâu đó trước đây. Nếu kênh của bạn trực tiếp, tất cả các yêu cầu dịch vụ sẽ được bao bọc cùng một giao dịch. Cách đơn giản nhất để thực hiện mong muốn của bạn, viết giao diện đơn giản @Gateway với @Transactional và gọi nó từ đầu luồng tin nhắn của bạn.

Để làm rõ một chút về giao dịch Understanding Transactions in Message flows

+0

bạn có thể đăng hoặc liên kết một số ví dụ về mã không? Tôi có cùng một vấn đề. Cảm ơn! –

+0

Tôi đã thêm vào câu trả lời của mình một liên kết về TX trong SI –

+0

Tôi đã đọc tài liệu này trước đây và vẫn còn nghi ngờ. Tôi đã đăng trường hợp của tôi trong http://stackoverflow.com/questions/18901510/keep-transaction-within-spring-integration-flow –

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