• No results found

How do you determine whether it would be better to use a Topic or Queue?

In document Java Interview Questions (Page 187-190)

Java Messaging using JMS & MOM

Application 1 similar setup as

Q. How do you determine whether it would be better to use a Topic or Queue?

You must choose to use a Topic if one of the following conditions applies:

• Same message must be replicated to multiple consumers (With Queue a message can only be consumed by one receiver).

• A message should be dropped if there are no active consumers that would select it.

• There are many subscribers each with a unique selector.

Q 91: Discuss some of the design decisions you need to make regarding your message delivery? SF DC FAQ

A 91:

During your design phase, you should carefully consider various options or modes like message acknowledgement modes, transaction modes and delivery modes. For example: for a simple approach you would not be using transactions and instead you would be using acknowledgement modes. If you need reliability then the delivery mode should be set to persistent. This can adversely affect performance but reliability is increased. If your message needs to be consumed only once then you need to use a queue (Refer Q90 in Enterprise section).

Design

decision Explanation Message

acknowledge ment options or modes.

Acknowledgement mode and transaction modes are used to determine if a message will be lost or re-delivered on failure during message processing by the target application. Acknowledgement modes are set when creating a JMS session.

InitialContext ic = new InitialContext(…);

QueueConnectionFactory qcf =

(QueueConnectionFactory)ic.lookup(“AccountConnectionFactory”);

QueueConnection qc = qcf.createQueueConnection();

QueueSession session = qc.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

In the above code sample, the transaction mode is set to false and acknowledgement mode is set to auto mode. Let us look at acknowledgement modes:

AUTO_ACKNOWLEDGE: The messages sent or received from the session are automatically acknowledged. This mode also guarantees once only delivery. If a failure occurs while executing onMessage() method of the destination MDB, then the message is re-delivered. A message is automatically acknowledged when it successfully returns from the onMessage(…) method.

DUPS_OK_ACKNOWLEDGE: This is just like AUTO_ACKNOWLEDGE mode, but under rare circumstances like during failure recovery messages might be delivered more than once. If a failure occurs then the message is re-delivered. This mode has fewer overheads than AUTO_ACKNOWLEDGE mode.

CLIENT_ACKNOWLEDGE: The messages sent or received from sessions are not automatically acknowledged. The destination application must acknowledge the message receipt. This mode gives an application full control over message acknowledgement at the cost of increased complexity. This can be acknowledged by invoking the acknowledge() method on javax.jms.Message class.

Transactional behavior

Transactional behavior is controlled at the session level. When a session is transacted, the message oriented middleware (MOM) stages the message until the client either commits or rolls back the transaction. The completion of a session’s current transaction automatically begins a new transaction.

The use of transactions in messaging affects both the producers and consumers of the messages as shown below:

MOM (aka Broker) Message

Producer Message

Consumer

1. commit 1. send

2. roll back

2. d

ispose of

the message

3. commit

3. dispose of

the message

4. roll back 4. resend Messaging - Transactional behavior

Producers [As per the above diagram]:

1’s Æ Commit: The MOM send the group of messages that have been staged.

2’s Æ Rollback: The MOM disposes of the group of messages that have been staged.

Consumers [As per the above diagram] :

3’s Æ Commit: The MOM disposes of the group of messages that have been staged.

4’s Æ Rollback: The MOM resends the group of messages that have been staged.

Transaction

modes In JMS, a transaction organizes a message or a group of messages into an atomic processing unit. So, if a message delivery is failed, then the failed message may be re-delivered. Calling the commit() method commits all the messages the session receives and calling the rollback method rejects all the messages.

InitialContext ic = new InitialContext(…);

QueueConnectionFactory qcf =

(QueueConnectionFactory)ic.lookup(“AccountConnectionFactory”);

QueueConnection qc = qcf.createQueueConnection();

QueueSession session = qc.createQueueSession(true, -1);

In the above code sample, the transaction mode is set to true and acknowledgement mode is set to -1, which means acknowledgement mode has no use in this mode. Let us look at transaction modes:

Message Driven Bean (MDB) with container managed transaction demarcation: A MDB participates in a container transaction by specifying the transaction attributes in its deployment descriptor. A transaction automatically starts when the JMS provider removes the message from the destination and delivers it to the MDB’s onMessage(…) method. Transaction is committed on successful completion of the onMessage() method. A MDB can notify the container that a transaction should be rolled back by setting the MessageDrivenContext to setRollBackOnly(). When a transaction is rolled back, the message is re-delivered.

public void onMessage(Message aMessage) {

if(someCondtionIsTrue) {

mdbContext.setRollbackOnly();

} else{

//everything is good. Transaction will be committed automatically on //completion of onMessage(..) method.

} }

Message Driven Bean (MDB) with bean managed transaction demarcation: If a MDB chooses not to participate in a container managed transaction then the MDB programmer has to design and code programmatic transactions. This is achieved by creating a UserTransaction object from the MDB’s MessageDrivenContext as shown below and then invoking the commit() and rollback() methods on this UserTransaction object.

public void onMessage(Message aMessage) {

UserTransaction uT = mdbContext.getUserTransaction();

uT.begin();

….

if(someCondtionIsTrue) { uT.rollback();

} else{

uT.commit();

} }

Transacted session: An application completely controls the message delivery by either committing or rolling back the session. An application indicates successful message processing by invoking Session class’s commit() method. Also it can reject a message by invoking Session class’s rollback() method. This committing or rollback is applicable to all the messages received by the session.

public void process(Message aMessage, QueueSession qs) { ….

if(someCondtionIsTrue) { qs.rollback();

} else{

qs.commit();

}

}

What happens to rolled-back messages?

Rolled back messages are re-delivered based on the re-delivery count parameter set on the JMS provider. The re-delivery count parameter is very important because some messages can never be successful and this can eventually crash the system. When a message reaches its re-delivery count, the JMS provider can either log the message or forward the message to an error destination. Usually it is not advisable to retry delivering the message soon after it has been rolled-back because the target application might still not be ready. So we can specify a time to re-deliver parameter to delay the re-delivery process by certain amount of time. This time delay allows the JMS provider and the target application to recover to a stable operational condition.

Care should be taken not to make use of a single transaction when using the JMS request/response paradigm where a JMS message is sent, followed by the synchronous receipt of a reply to that message.

This is because a JMS message is not delivered to its destination until the transaction commits, and the receipt of the reply will never take place within the same transaction.

Note: when you perform a JNDI lookup for administered objects like connection factories, topics and/or queues, you should use the logical reference java:comp/env/jms as the environment subcontext. It is also vital to release the JMS resources like connection factories, sessions, queues, topics etc when they are no longer required in a try{} and finally{} block.

Message delivery options

Q. What happens, when the messages are with the JMS provider (i.e. MOM) and a catastrophic failure occurs prior to delivering the messages to the destination application?

The messages will be lost if they are non-durable. The message’s state whether they are lost or not does not depend on acknowledgement modes or transaction modes discussed above. It depends on the delivery mode, which defines whether the message can be durable (aka persistent) or non-durable (aka non-persistent). If you choose the durable delivery mode then the message is stored into a database or a file system by the JMS server before delivering it to the consumer. Durable messages have an adverse effect on performance, but ensure that message delivery is guaranteed. Durability can only be established for the publish/subscribe model.

Q. What are the values need to be set to register subscription and establish durability?

• SubscriptionID: Subscribers should be registered with a unique ID that is retained by the JMS server.

• ClientID: is a unique id by which the JMS server knows how to deliver durable messages to the registered subscribers when they become available.

subscribeConnection.setClientID("id-123");

subscribeConnection.start();

subscribeSession = subscribeConnection.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE);

subscriber = subscribeSession.createDurableSubscriber(resDestination,

"subscription-id-123");

Q 92: How does XML over HTTP compare with XML using JMS? Why use XML with JMS? SF SE

A 92: XML itself does not specify a communications infrastructure. If you do not need reliable and scalable messaging then use XML over HTTP. This approach is sufficient for rudimentary applications but does not scale for distributed applications across multiple systems.

XML over HTTP XML over JMS

Simple to implement, widely compatible and has less performance overhead but HTTP does not provide reliability in terms of guaranteed delivery because there is no message persistence, no inherent reporting facility for failed message delivery and no guaranteed once only delivery. The application programmer must build these services into the application logic to provide reliability &

persistence, which is not an easy task.

This is an easy to implement, reliable, scalable and robust solution. The main disadvantage of this approach is that the JMS providers (i.e. Message Oriented Middleware) use a proprietary protocol between producer and consumer. So to communicate, you and your partners need to have the same MOM software (E.g. MQSeries). JMS allows you to toss one MOM software and plug-in another but you cannot mix providers without having to buy or build some sort of bridge.

In document Java Interview Questions (Page 187-190)

Related documents