Quality of Service
ServiceMix can handle four parameters that affect the Quality of Service for a given exchange:
- clustered
- synchronous
- transactional
- persistent
These combined parameters defined the QoS for a given exchange, and depending on this QoS, a flow will be selected of convey this particular exchange.
Synchronicity & Transactionality
If syncSend is used to send a message exchange, the implied semantic is that the transaction flows with the exchange and that the provider has to answer synchronously and enlist any needed resources inside the transaction. By setting the autoEnlistInTransaction flag to true on the container, each time a JBI exchange is sent, it will be enlisted in the current transaction as shown below:
Transactions within a synchronous flow are not created by default. Currently, the only ServiceMix component able to start transactions is the servicemix-jms when used with JCA.
If send is used, the act of sending the message will be enlisted in the current transaction, but the exchange processing will be defered and handled in its own thread. To use transactions with asynchronous message exchanges, the JCA flow must be used. As shown below, the scope of a transaction is bounded by the asynchronous message exchange.
Responding to a transactional synchronous message may not be always a possible option for a given component acting as a provider.
For example, an asynchronous BPEL process may not support this processing behavior.
...
Actually, all QoS combinations can be handled by one or the other flow, but exchanges that are clustered, transactional and synchronous or persistent, transactional and synchronous.
St: A, S
Seda: A, S, ST
Jms: A, AC, ACP, S, SC, SCP
Jca: A, AC, ACP, ACT, ACPT, APT
Unhandled: SCT, SPT, SCPT
...
| QoS attribute |
---|---|
A | Asynchronous |
S | Synchronous |
C | Clustered (means that the same endpoint is activated on the local container and at least a remote container) |
P |
...
Persistent | |
R |
...
Remote (means that the endpoint is not available locally, but only on a remote container) | |
T |
...
Transactional |
Flow | Handled QoS |
---|---|
St | A, S |
Seda | A, S, ST |
Jms | A, AC, ACP, S, SC, SCP |
Jca | A, AC, ACP, ACT, ACPT, APT |
Unhandled | SCT, SPT, SCPT |
Currently, there is no distinction between C (clustered) and R (remote), though this should be enhanced to provider support for SCT which would be handled as ST (using the local endpoint).
We would then have,
Flow | Handled QoS |
---|---|
St |
...
A, AC, S, SC | |
Seda |
...
A, AC, S, SC, ST, SCT | |
Jms |
...
A, AC, ACP, AR, ARP, S, SC, SCP, SRP | |
Jca |
...
A, AC, ACP, ACT, ACPT, APT, AR, ARP, ART, ARPT | |
Unhandled |
...
SPT, SCPT, SRPT |
Sending synchronous transactional exchanges
Code Block | ||
---|---|---|
| ||
TransactionManager tm = (TransactionManager) getContext().getTransactionManager(); tm.begin(); InOnly me = createInOnly(); getContext().getDeliveryChannel().sendSync(me); tm.commit(); |
Code Block | ||
---|---|---|
| ||
TransactionManager tm = (TransactionManager) getContext().getTransactionManager(); tm.begin(); InOut me = createInOut(); getContext().getDeliveryChannel().sendSync(me); // retrieve the out message me.setStatus(ExchangeStatus.DONE); getContext().getDeliveryChannel().sendSyncsend(me); tm.commit(); |
Sending asynchronous transactional exchanges
Code Block | ||
---|---|---|
| ||
TransactionManager tm = (TransactionManager) getContext().getTransactionManager(); tm.begin(); InOnly me = createInOnly(); getContext().getDeliveryChannel().send(me); tm.commit(); |
Code Block | ||
---|---|---|
| ||
TransactionManager tm = (TransactionManager) getContext().getTransactionManager(); tm.begin(); InOut me = createInOut(); getContext().getDeliveryChannel().send(me); tm.commit(); |
Receiving and processing transactional exchanges
...
You can check if a given exchange is transactional by using:
Code Block | ||
---|---|---|
| ||
boolean transactional = exchange.getProperty("javax.jbi.transaction.jta") != null;
|
and you can check if the exchange is synchronous by using:
Code Block | ||
---|---|---|
| ||
boolean synchronous = exchange.getProperty("javax.jbi.messaging.sendSync") != null;
|
If your component is a MessageExchangeListener, the delivery will automatically be
transacted. You just need to use sendSync if the exchange is synchronous and send
if the exchange is not.Created by Guillaume Nodet
On Fri Jun 02 18:41:25 CEST 2006
Using TimTam