[jboss-user] [JBoss Messaging] - Re: OrderingGroup and Transaction Rollback

mclu do-not-reply at jboss.com
Mon Jun 8 08:13:54 EDT 2009


Hi!

Ok. Here is my method which receives the message from the queue.
There is also a slowdown feature but this can be ignored here.
The method is called at a statefull sessionbean with CMT so a transaction is just started.


  |  Session session = null;
  |         Connection conn = null;
  |         MessageConsumer consumer = null;
  |         try {
  |             conn = getConnection();
  |             boolean transacted = true;
  |             session = conn.createSession(transacted, Session.SESSION_TRANSACTED);
  | 
  |             consumer = session.createConsumer(m_queue);
  | 
  |             Logger.debug(this, "blocking to receive message from queue");
  | 
  |             // keep waittime small to ensure handling inside the transaction
  |             Message msg = consumer.receive(20000);
  |             if (msg != null) {
  |                 // get deliverycount of the message. If it is the first time the count is 1
  |                 int redeliveryCount = msg.getIntProperty("JMSXDeliveryCount");
  |                 if (redeliveryCount > 1) {
  |                     // at least the second retry so wait to slow consuming down
  |                     // in ms: 10, 20, 40, 80, .... 102400 (at the 10 delivery)
  |                     long waittime = (long) (10 * Math.pow(2, redeliveryCount));
  |                     Logger.info(this, "Redelivery is slowed down. Waittime (ms):" + waittime);
  |                     try {
  |                         Thread.sleep(waittime);
  |                     }
  |                     catch (InterruptedException e) {
  |                         // ignore
  |                     }
  |                 }
  |                 // HERE the message is delegated to a handler. see expl. below
  |                 jmsMessageHandler.handleMessage(msg);
  |             }
  |         }
  |         catch (JMSException e) {
  |             throw new RuntimeException("Problems handling message.", e);
  |         }
  |         finally {
  |             if (consumer != null)
  |                 try {
  |                     consumer.close();
  |                 }
  |                 catch (Exception ignore) {
  |                 }
  |             if (session != null)
  |                 try {
  |                     session.close();
  |                 }
  |                 catch (Exception ignore) {
  |                 }
  |             if (conn != null)
  |                 try {
  |                     conn.close();
  |                 }
  |                 catch (Exception ignore) {
  |                 }
  |         }
  | 

So I open a connection, create a transacted session and receive ONE message. Then I delegate the message to a handler. In the final I close the resources.

The handler just uses:
private SessionContext ctx;
and then calls ctx.setRollbackOnly();

When I debug I see that the first message is delivered. The OrderingGroup.markSending() is called and the handler handles the message. 
Then while the transaction is commited the unregister is called.

Now comes the failing message where the transaction is marked as rollback only. While the session is closed in the final block the unregister method is called again!! So the message is removedfrom the linked list!
Stack trace:

OrderingGroup.unregister(MessageReference) line: 121	
  | OrderingGroupMonitor.unmarkSending(MessageReference) line: 178	
  | MessagingQueue(ChannelSupport).cancelInternal(MessageReference) line: 609	
  | MessagingQueue(PagingChannelSupport).cancelInternal(MessageReference) line: 323	
  | MessagingQueue(ChannelSupport).cancel(Delivery) line: 328	
  | SimpleDelivery.cancel() line: 110	
  | ServerSessionEndpoint.cancelDeliveryInternal(Cancel) line: 1643	
  | ServerSessionEndpoint.cancelDelivery(Cancel) line: 456	
  | SessionAdvised.org$jboss$jms$server$endpoint$advised$SessionAdvised$cancelDelivery$aop(Cancel) line: 145	
  | SessionAdvised$cancelDelivery_2980985335510575813.invokeNext() line: not available	
  | ServerLogInterceptor.invoke(Invocation) line: 105	
  | SessionAdvised$cancelDelivery_2980985335510575813.invokeNext() line: not available	
  | SessionAdvised.cancelDelivery(Cancel) line: not available	
  | SessionCancelDeliveryRequest.serverInvoke() line: 84	
  | JMSServerInvocationHandler.invoke(InvocationRequest) line: 143	
  | SSLBisocketServerInvoker(ServerInvoker).invoke(InvocationRequest) line: 862	
  | ServerThread.processInvocation(SocketWrapper) line: 609	
  | ServerThread.dorun() line: 421	
  | ServerThread.run() line: 174	
  | 


What I see in OrderingGroupMonitor is that unmarksending AND messageCompleted has more or less the same code? Can this be right?
Both call:
OrderingGroup group = orderingGroups.get(grpName);
         if (group != null)
         {
            group.unregister(ref);
         }


Greets

View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4236007#4236007

Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4236007



More information about the jboss-user mailing list