cancel
Showing results for 
Search instead for 
Did you mean: 

MDB Rollback

Former Member
0 Kudos

Hi,

I have a collection of MDBs and due to different errors (jms resources / dbs not there) there are exceptions being met.

However, the messages are not being rolled back, but are being consumed along with the exception. I throw a runtimeException within the onMessage method.

Is there something specific that needs set to allow for automatic rollback?

Regards,

Andrew

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Closed / set to answered as open with SAP.

Vlado
Advisor
Advisor
0 Kudos

Hi Andrew,

It's not clear what you mean by "the messages are not being rolled back". Which operation is being rolled back (send, receive?) and what exactly is not working as expected?

Can you please describe in more details the flow of your app logic?

Regards,

\-- Vladimir

Former Member
0 Kudos

Hi Vladimir,

I experienced these problems when i was setting up the application and making sure the db settings were correct.

I was able to put a message on jms queue, which our application listens to.

Upon receiving the message, the application tries to write to the database. At this point I did not have the db connection setup correctly, and so an error was reported. However the message was consumed from the jms queue.

I would have thought that the message would have been rolled back on to the queue, so that processing would continue once the problem was fixed without the loss of messages.

For example, if a db was to go down during processing, I would still expect the messages to be on the queue, and once the db came back online, then messages would start to be consumed from the queue after succesfully being processed by the MDB.

Regards,

Andrew

Vlado
Advisor
Advisor
0 Kudos

Hi Andrew,

It's clearer now. So, I can think of two possible things that might have been happening in your case:

A) The message is auto acknowledged. This might happen if your MDB is configured to use the NotSupported transaction attribute or if it uses a non-XA connection factory. Please check this.

B) The SAP JMS Provider attempts to deliver a message to a consumer until the message is acknowledged. The default number of attempts is 5 and the default interval between two consecutive attempts is 2 seconds. You can tweak these settings in the jms-resources.xml according to your particular needs. For more information please refer to the following documentation:

[Handling Exceptions|http://help.sap.com/saphelp_nwce10/helpdata/en/46/31f5f3db1214dce10000000a155369/frameset.htm]

[Handling Dead Messages|http://help.sap.com/saphelp_nwce10/helpdata/en/46/b10fcade5c0763e10000000a1553f6/frameset.htm]

[Property Reference|http://help.sap.com/saphelp_nwce10/helpdata/en/46/3156399f1214dfe10000000a155369/frameset.htm]

HTH!

\-- Vladimir

Former Member
0 Kudos

Vladimir,

I have checked the settings, and the queues have now been changed to use an XA connection factory, along with settings to resend the message every minute, indefinately.

However, when I sent an 'error' message in (which i knew would cause an exception), the same thing happened - the message just seemed to be consumed.

The following message was in the trace/log files.

Application exception happened while invoking onMessage() method. It was caught and suppressed in the ServerSession. For more details see the trace file

It is not in the sapDefaultErrorQueue either. It seems to have vanished....

The queues have the following properties:

<property>

<description>

Message Delivery Attempts Limited - We dont limit...

</description>

<config-property-name>

deliveryAttemptsLimited

</config-property-name>

<config-property-value>false</config-property-value>

</property>

<property>

<description>Delay in Milliseconds</description>

<config-property-name>

deliveryDelayInterval

</config-property-name>

<config-property-value>60000</config-property-value>

</property>

Is there anything else i was missing?

Regards,

Andrew

Vlado
Advisor
Advisor
0 Kudos

Hi Andrew,

Are you using the SR3 trial version from SDN?

Have you verified that the transaction attribute for the onMessage() method is Required?

Is the XA connection factory you're using deployed with a jms-resources.xml?

\-- Vladimir

Former Member
0 Kudos

Vladimir,

the version of the NWDS is SP04.

I dont think that the server is a trial.

The connection factory is described here:

<connection-factory>

<name>jms/dts/queueConnectionFactory</name>

<sap-local-factory-type>

<type>javax.jms.XAQueueConnectionFactory</type>

<virtual-provider>default</virtual-provider>

</sap-local-factory-type>

</connection-factory>

I dont think I understand about the onMessage transaction attribute - can you explain this, or point me in the right direction.

Many thanks.

Regards,

Andrew

Vlado
Advisor
Advisor
0 Kudos

Have you specified a transaction attribute for the onMessage() method or for the MDB itself - either with the @TransactionAttribute annotation or with the <trans-attribute> tag in the ejb-jar.xml?

Former Member
0 Kudos

Vladimir,

I have checked the ejb-jar.xml, and added in the following xml to allow transactions:

<container-transaction>

<method>

<ejb-name>FileRegisterMDB</ejb-name>

<method-name>onMessage</method-name>

<method-params>

<method-param>javax.jms.Message</method-param>

</method-params>

</method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

all in the assembly descriptor tag of course....

It still consumed the message, but now is giving the following stacktrace.

Exception com.sap.engine.services.ts.exceptions.BaseRollbackException: Status of ( SAP J2EE Engine JTA Transaction : [03a5bffffffa6005ffffffa2] ) should be active, but it is STATUS_MARKED_ROLLBACK = 1.

at com.sap.engine.services.ts.jta.impl.TransactionImpl.registerSynchronization(TransactionImpl.java:638)

at org.springframework.transaction.jta.JtaTransactionManager.doRegisterAfterCompletionWithJtaTransaction(JtaTransactionManager.java:928)

at org.springframework.transaction.jta.JtaTransactionManager.registerAfterCompletionWithExistingTransaction(JtaTransactionManager.java:894)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerAfterCompletion(AbstractPlatformTransactionManager.java:885)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:782)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:730)

at org.springframework.transaction.support.TransactionTemplate.rollbackOnException(TransactionTemplate.java:153)

at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)

at com.amtsybex.dts.ejb.AbstractDtsMessageDrivenBean.onMessage(AbstractDtsMessageDrivenBean.java:132)

at com.amtsybex.dts.ejb.FileRegisterMDBBean.onMessage(FileRegisterMDBBean.java:59)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sap.engine.services.ejb3.runtime.impl.RequestInvocationContext.proceedFinal(RequestInvocationContext.java:43)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:166)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatesTransition.invoke(Interceptors_StatesTransition.java:19)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Resource.invoke(Interceptors_Resource.java:71)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_MessageListenerType.invoke(Interceptors_MessageListenerType.java:110)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:189)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_StatelessInstanceGetter.invoke(Interceptors_StatelessInstanceGetter.java:16)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_SecurityCheck.invoke(Interceptors_SecurityCheck.java:21)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_ExceptionTracer.invoke(Interceptors_ExceptionTracer.java:16)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_Lock.invoke(Interceptors_Lock.java:21)

at com.sap.engine.services.ejb3.runtime.impl.AbstractInvocationContext.proceed(AbstractInvocationContext.java:177)

at com.sap.engine.services.ejb3.runtime.impl.DefaultInvocationChainsManager.startChain(DefaultInvocationChainsManager.java:133)

at com.sap.engine.services.ejb3.runtime.impl.DefaultEJBProxyInvocationHandler.invoke(DefaultEJBProxyInvocationHandler.java:164)

at com.sap.engine.services.ejb3.runtime.impl.MDBProxyInvocationHandler.invoke(MDBProxyInvocationHandler.java:71)

at $Proxy37_10002.onMessage(Unknown Source)

at com.sap.jms.resourceadapter.RaServerSession.onMessage(RaServerSession.java:183)

at com.sap.jms.client.session.Session.run(Session.java:620)

at com.sap.jms.resourceadapter.RaServerSession.run(RaServerSession.java:255)

at com.sap.engine.services.connector.jca15.work.TaskImpl.run(TaskImpl.java:424)

at com.sap.engine.core.thread.execution.Executable.run(Executable.java:108)

at com.sap.engine.core.thread.execution.CentralExecutor$SingleThread.run(CentralExecutor.java:304)

Is there something I have missed?

Regards,

Andrew

Former Member
0 Kudos

Hi,

Just some more info on this.

The mdbs that are being used are ejb 2.1 and as such are using the old ejb-j2ee-engine.xsd.

Should I be setting the isolation-level in here?

Regards,

Andrew

Vlado
Advisor
Advisor
0 Kudos

Hi Andrew,

Then I really have no further clues.

I believe we can't do much to debug this issue here, that's why I'd suggest to open a support ticket for this case.

Regards,

\-- Vladimir

Former Member
0 Kudos

Many thanks for your help Vladimir. I shall pursue that course of action.

Just as a finishing note, I have tried to recreate the problem, with a simple 1-mdb application.

Turns out that the jms resources are ignoring the property settings, and whenever the following configuration is used, the message is rolled back successfully 10 times and then gets ditched.

The following is the ejb-jar.xml and jms-resources.xml

<jms-resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="jms-resources.xsd">

<connection-factory>

<name>jms/mortyQueueConnectionFactory</name>

<sap-local-factory-type>

<type>javax.jms.XAQueueConnectionFactory</type>

<virtual-provider>default</virtual-provider>

</sap-local-factory-type>

</connection-factory>

<destination>

<name>jms/mortyQueue</name>

<type>javax.jms.Queue</type>

<sap-local-destination-type>

<virtual-provider>default</virtual-provider>

<property>

<config-property-name>

deliveryDelayInterval

</config-property-name>

<config-property-value>5000</config-property-value>

</property>

</sap-local-destination-type>

<property>

<config-property-name>

deliveryDelayInterval

</config-property-name>

<config-property-value>5000</config-property-value>

</property>

</destination>

</jms-resources>

<ejb-jar

xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

id="ejb-jar_ID"

version="2.1"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">;

<display-name>transactionExercise</display-name>

<enterprise-beans>

<message-driven>

<description>Some random description</description>

<display-name>testerMDB</display-name>

<ejb-name>testerMDB</ejb-name>

<ejb-class>com.morty.test.trans.testMDB</ejb-class>

<messaging-type>javax.jms.MessageListener</messaging-type>

<transaction-type>Container</transaction-type>

<message-destination-type>javax.jms.Queue</message-destination-type>

</message-driven>

</enterprise-beans>

<assembly-descriptor>

<container-transaction>

<method>

<ejb-name>testerMDB</ejb-name>

<method-name>onMessage</method-name>

<method-params>

<method-param>javax.jms.Message</method-param>

</method-params>

</method>

<trans-attribute>Required</trans-attribute>

</container-transaction>

</assembly-descriptor>

and the ejb-j2ee-engine.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<ejb-j2ee-engine

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="ejb-j2ee-engine.xsd">

<enterprise-beans>

<enterprise-bean>

<ejb-name>testerMDB</ejb-name>

<jndi-name>jms/mortyQueue</jndi-name>

<message-props>

<destination-name>jms/mortyQueue</destination-name>

<connection-factory-name>jms/mortyQueueConnectionFactory</connection-factory-name>

<property>

<property-name>InitialSize</property-name>

<property-value>1</property-value>

</property>

<property>

<property-name>MaxSize</property-name>

<property-value>1</property-value>

</property>

<property>

<property-name>ResizeStep</property-name>

<property-value>1</property-value>

</property>

<property>

<property-name>sleep-between-attempts</property-name>

<property-value>1000</property-value>

</property>

</message-props>

</enterprise-bean>

</enterprise-beans>

</ejb-j2ee-engine>

But i shall continue on....

Many thanks again.

Regards,

Andrew

Former Member
0 Kudos

I think i know what is going on.....

My XAQueueConnectionFactory is being deployed as a QueueConnectionFactory instead....

Bizarre...