JMS - rollback but no redelivery
All,
I have a simple pub/sub on weblogic 8.1 that has a independent thread doing sychronous consumption. The session is transacted. Everything is smooth except when I attempt to rollback a transaction. In such a case, the message is not redelivered when I re-invoke the receive method 1 minute later. It is discarded.
Looking at the pending messages on the queue, the message is always discarded 40 seconds after transaction is rolled back. If I shorten my wait and call the receive method 20 seconds after the rollback, the message is discarded after 20 seconds on the receive call. I was expecting to pull the message I had previously pulled.
Message has infinite lifespan, redelivery limit is infinite. I also created a template and hardcoded the redelivery limit for the jms server and topic with no success.
Any pointers or leads would be appreciated.
thanks - Dan
Tom,
I pasted relevant pieces of config.xml and the listener code below, I hope it's intelligible. We're using the default ConnectionFactory.
We're using topics and TopicSubscriber for consumption. The flow here is consume a message through receive(), attempt to deliver this message to our client, rollback in case of failure, sleep 60 seconds, then attempt redelivery. When receive is invoked the second time, the message is gone. TopicSession code and the line that does invokes the rollback are surrounded by -------------.
- Dan
------------portions of config.xml---------------
(the first JmsServer entry was not created by me, second was)
<JMSServer Name="WSStoreForwardInternalJMSServerwlsD01S001"
Store="FileStore" Targets="wlsD01S001">
<JMSQueue CreationTime="1085198870801"
JNDIName="jms.internal.queue.WSStoreForwardQueue"
JNDINameReplicated="false" Name="WSInternaljms.internal.queue.WSStoreForwardQueuewlsD01S001"/>
<JMSQueue CreationTime="1085198871294"
JNDIName="jms.internal.queue.WSDupsEliminationHistoryQueue"
JNDINameReplicated="false" Name="WSInternaljms.internal.queue.WSDupsEliminationHistoryQueuewlsD01S001"/>
</JMSServer>
<JMSServer Name="Gov JMS Server WLSD04S001"
Store="Gov JMS File Store" Targets="wlsD01S001" TemporaryTemplate="MyJMS Template">
<JMSTopic CreationTime="1135118604257" JNDIName="GovJMSTopic"
Name="Gov JMS Topic" Template="MyJMS Template"/>
</JMSServer>
<JMSFileStore Directory="govJmsFileStore" Name="Gov JMS File Store"/>
<JMSTemplate ExpirationPolicy="Discard" Name="MyJMS Template" RedeliveryDelayOverride="0" RedeliveryLimit="250"/>
-----------------portions of listener code---------------
public class RubyMessageListener extends Thread
private TopicConnection topicConnection = null;
private TopicSession topicSession = null;
private TopicSubscriber topicSubscriber = null;
Context jndiContext = null;
private RubyMessageListener() {;}
public RubyMessageListener(String url, AgmemsFilter aFilter, ClientManager cmParam)
throws NamingException, JMSException, ConfigurationException
Create a JNDI API InitialContext object if none exists
yet.
jndiContext = new InitialContext();
We're taking care of the connection establishment at object
startup time so that if we throw exception, we can throw
exception back up to subscribe caller who can report NG to
client
Look up connection factory and queue. If either does
not exist, exit.
TopicConnectionFactory topicConnectionFactory = null;
Topic topic = null;
TextMessage message = null;
topicConnectionFactory = (TopicConnectionFactory) PortableRemoteObject.narrow(jndiContext.lookup("weblogic.jms.ConnectionFactory"), TopicConnectionFactory.class);
topic = (Topic) PortableRemoteObject.narrow(jndiContext.lookup("GovJMSTopic"), Topic.class);
Create connection.
Create session from connection; true means session is
transacted.
Create receiver, then start message delivery.
Close connection.
topicConnection = topicConnectionFactory.createTopicConnection();
topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
topicSubscriber = topicSession.createSubscriber(topic);
topicConnection.start();
myLogger.info("RubyMessageListener(): queue connection has been started, now listening on events");
public void confirmAndFallout(TopicSession ts, String sleepTime, boolean commitFlag)
try
if (commitFlag)
ts.commit();
myLogger.info("confirmAndFallout(): transaction is committed.");
else
ts.rollback();
myLogger.info("confirmAndFallout(): transaction successfully rolled back, must wait the sleepTime, " + sleepTime + " ms, before pulling message off of queue.");
try
Thread.sleep(Integer.parseInt(sleepTime));
catch (Exception e)
myLogger.error("confirmAndFallout(): After rollback, thread sleep failed, moving on without sleep.");
myLogger.info("confirmAndFallout(): sleep has been completed, return to event listening.");
return;
catch (JMSException je)
try
myLogger.error("confirmAndFallout(): Unable to confirm delivery transaction, sleep, then try once more before bailing.");
Thread.sleep(Integer.parseInt(sleepTime));
if (commitFlag)
ts.commit();
myLogger.info("confirmAndFallout(): transaction is committed.");
else
ts.rollback();
myLogger.info("confirmAndFallout(): transaction successfully rolled back.");
catch (Exception e)
myLogger.error("confirmAndFallout(): The second attempt at jms confirmation has failed, return.");
return;
public void run()
try
myLogger.info("run(): Client has asked us to begin pulling events for url: " + listenerUrl);
while (!haltFlag)
myLogger.info("run(): BACK up at top of receive loop");
StringBuffer errstr = new StringBuffer();
//receive will initiate our jms transaction,
//commit or rollback will end the transaction
//receive is blocking, wait 55 minutes before committing
//transaction and looping again. We do this to avoid
//default 60 minute transaction timeout
Message m = topicSubscriber.receive(3300000);
if (m != null)
if (m instanceof TextMessage)
TextMessage message = (TextMessage) m;
String messageText = "";
String eventType = "";
Document doc;
Node rootNode=null;
try
messageText = message.getText();
myLogger.info("run(): the following message has been pulled from the queue: " + messageText);
eventType = "";
doc = rubyxml.stringToXML(messageText);
rootNode = doc.getFirstChild();
catch (Exception e)
myLogger.error("run(): unable to understand the message we've pulled off the queue, commit transaction and continue. " + listenerUrl + " will not be receiving this message.");
confirmAndFallout(topicSession, listenerSleep, true);
continue;
String operationNodeName = "";
if (rootNode!=null)
operationNodeName = rootNode.getNodeName();
myLogger.info("run(): operationNodeName: " + operationNodeName);
if (operationNodeName.equals("tktInfoEvt"))
eventType = "tktInfoEvt";
else if (operationNodeName.equals("prmInfoEvt"))
eventType = "prmInfoEvt";
else if (operationNodeName.equals("rubyFacilityStatusEvt"))
eventType = "rubyFacilityStatusEvt";
else if (operationNodeName.equals("killEvt"))
eventType = "killEvt";
else
eventType = "heartbeatEvt";
/** If the message is a rubyFacilityStatusEvt,
tktInfoEvt, or prmInfoEvt
- perform filter(listenerUrl, mcn) to determine
whether our client cares about this message
- if client cares, stamp(url) to refresh clock,
convert the xml string to java class, and send
message
- if client does not care, invoke discardedMsg(mcn)
and commit the transaction
- if ws request succeeds, commit
- if ws request fails, rollback and sit tight
for one minute
else if (eventType.equals("rubyFacilityStatusEvt") ||
eventType.equals("tktInfoEvt") ||
eventType.equals("prmInfoEvt"))
String mcn = rubyxml.getValueByTag((Element)rootNode, "mcn", errstr);
if (gs.filter(listenerUrl, mcn)
== AgmemsFilter.FILTER_PASSED)
myLogger.info("run(): we've pulled a " + eventType + " message off of the queue and it's time to send it out to client: " + listenerUrl);
messageCount += 1;
Socket agmemsSocket = null;
try
if (eventType.equals("rubyFacilityStatusEvt"))
agmemsSocket = HttpUtilities.sendCommand(cu.populateFacilityEvt(facStatusServiceUrl, messageText, messageCount, facStatusAction, rdate, agmemsUsername, agmemsPassword, "", false), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), facStatusServiceUrl);
else if (eventType.equals("tktInfoEvt"))
agmemsSocket = HttpUtilities.sendCommand(cu.populateTicketEvt(tktInfoServiceUrl, messageText, messageCount, tktInfoAction, rdate, agmemsUsername, agmemsPassword), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), tktInfoServiceUrl);
else
agmemsSocket = HttpUtilities.sendCommand(cu.populatePrmEvt(prmInfoServiceUrl, messageText, messageCount, prmInfoAction, rdate, agmemsUsername, agmemsPassword), agmemsHost, Integer.parseInt(agmemsPort), Integer.parseInt(agmemsTimeout), prmInfoServiceUrl);
catch (Exception e)
//these are the kind of failures,
//timeout, socketException, etc. that we
//would like to retry
myLogger.error("run(): ERROR, " + eventType + " push was unable to be sent to " + listenerUrl + " because of following exception, rolling back transaction." + e);
------------------------ confirmAndFallout(topicSession, listenerSleep, false);
continue;
myLogger.info("run(): Continued to readReplyFromSocket");
StringBuffer respStr = new StringBuffer();
try
HttpUtilities.readReplyFromSocket
(agmemsSocket, respStr);
myLogger.info("run(): response returned was " + respStr);
catch (Exception ie)
//rollback, something wrong on client side
myLogger.error("run(): ERROR, " + eventType + " NOT delivered to " + listenerUrl + " rolling back transaction. " + ie.toString());
confirmAndFallout(topicSession, listenerSleep, false);
continue;
int agmemsMessageNumber=0;
agmemsMessageNumber =
cu.parseAgmemsResponse(respStr.toString());
if ((agmemsMessageNumber==-1) ||
(agmemsMessageNumber!=messageCount))
confirmAndFallout(topicSession, listenerSleep, true);
myLogger.error("run(): ERROR, " + eventType + " push response came back with NOT delivered to " + listenerUrl + " confirming transaction.");
else
confirmAndFallout(topicSession, listenerSleep, true);
myLogger.info("run(): " + eventType + " delivered to " + listenerUrl + " and transaction is committed.");
//Assumes CLIENT_INACTIVE return
else
//commit for cleanup only
confirmAndFallout(topicSession, listenerSleep, true);
setHaltFlag(true);
myLogger.error("run(): " + eventType + " NOT delivered to " + listenerUrl + ", CLIENT_INACTIVE, halting message receive on this listener.");
else
myLogger.error("run(): we've pulled a text message from the queue that is UNKNOWN, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
else
myLogger.error("run(): we've pulled a message from the queue that is UNKNOWN and not text, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
else
myLogger.error("run(): something strange happened, receive() returned with NO MESSAGE, commit and continue.");
confirmAndFallout(topicSession, listenerSleep, true);
catch (JMSException je)
myLogger.error("run(): ERROR, exception, cleanup connections: " + je.toString());
catch (Exception e)
myLogger.error("run(): ERROR, exception, cleanup connections: " + e.toString());
finally
myLogger.error("run(): broken out of message receive loop, closing session, subscription, and topicConnection and KILLING this thread.");
if (topicConnection != null)
try
cm.listenerTable.remove(listenerUrl);
topicSession.close();
topicSubscriber.close();
topicConnection.close();
catch (JMSException e)
myLogger.error("run(): As part of cleanup process, there was an exception attempting to close our topicConnection.");
Message was edited by:
whoopsy
Similar Messages
-
Hi,
Our scenario is to En-queue all the request if the service is unavailable. We have defined the quota size for the JMS Queue as 100. After the Quota size is reached the Weblogic will throw a error to about the queue full to the invoking application. The problem currently we are facing is after the queue size has reached its full capacity the weblogic sends the invoking application the response in case of service down. But after the service is up and running the messages in the queue are not consumed by the service.
Below are the Logged details:
<Aug 8, 2011 5:24:05 AM EDT> <Info> <EJB> <ussbsoadev01> <osb_server1> <[ACTIVE] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)'> <<anonymous>> <> <6f1df4530fc51bf1:-2f212fa5:131a870c228:-7ffd-000000000000012a> <1312795445639> <BEA-010213> <Message-Driven EJB: RequestEJB-3648719559143300741--42d05813.1319974a3a5.-7fd1's transaction was rolled back. The transaction details are: Xid=BEA1-08A8CD91E97316C33200(51290702),Status=Rolled back. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction],numRepliesOwedMe=0,numRepliesOwedOthers=0,seconds since begin=122,seconds left=60,XAServerResourceInfo[WLStore_cog_osb_domain_FileStore]=(ServerResourceInfo[WLStore_cog_osb_domain_FileStore]=(state=rolledback,assigned=osb_server1),xar=WLStore_cog_osb_domain_FileStore115319941,re-Registered = false),SCInfo[cog_osb_domain+osb_server1]=(state=rolledback),OwnerTransactionManager=ServerTM[ServerCoordinatorDescriptor=(CoordinatorURL=osb_server1+156.70.10
We dont know what is exact reason why the messages are not picked even though the service is up and running fine.
Help me in this.
ThanksCommit and rollback only work for transactions that add, change, and delete records. You can't commit or rollback a Drop Table. And from what you say, it appears that as soon as you try, everything up to the non-committable statement is committed.
-
Send JMS rollbacked message to del letter queue
Hi,
I have one MDB, which calls an EJB Stateless. This EJB belongs to a container
managed transaction and it can make a Rollback (setRollbackOnly()).
My problem is that if the MDB belongs to the container-managed transaction, when
a rollback is sent, the received JMS message is put back in the JMS queue. But,
I want to send it in a del letter queue.
And if the MDB does not belong to the transaction, I could not know that the transaction
is rollbacked!
Do you know how can I resolve this problem?
Thanks
Charles
Charles,
Search the JMS newsgroup with Google and you should find the answer.
There is a setting (I know it exists but I've never used it and don't
know the exact details on how to use it) that you can change and after a
few tries the message is put into another queue.
--dejan
Charles Desmoulins wrote:
>Hi,
>
>I have one MDB, which calls an EJB Stateless. This EJB belongs to a container
>managed transaction and it can make a Rollback (setRollbackOnly()).
>
>My problem is that if the MDB belongs to the container-managed transaction, when
>a rollback is sent, the received JMS message is put back in the JMS queue. But,
>I want to send it in a del letter queue.
>
>And if the MDB does not belong to the transaction, I could not know that the transaction
>is rollbacked!
>
>Do you know how can I resolve this problem?
>
>Thanks
>Charles
>
>
>
-
Trying to start the j2ee to be the JMS provider but why error
Anyone knows why I can't start the j2ee ..which I hope to use it as the JMS provider. I am trying to try the e.g. from JMS tutorial....
But it seems that I can't start the j2ee in the first place 'cos error say that I have another instance running...(but I didn't start anything in the first place). How should I solve this?
How could I stop the j2ee server....I tried the command
j2ee -stop but cannot..
Anyone can help?
AG
G:\jmseg\simple>j2ee -verbose
J2EE server listen port: 1050
java.lang.RuntimeException: Could not initialize j2ee server. Possible cause cou
ld be another instance of the server already running.
at com.sun.enterprise.iiop.POAProtocolMgr.initializeNaming(POAProtocolMg
r.java:134)
at com.sun.enterprise.server.J2EEServer.run(J2EEServer.java:227)
at com.sun.enterprise.server.J2EEServer.main(J2EEServer.java:918)
java.lang.RuntimeException: Could not initialize j2ee server. Possible cause cou
ld be another instance of the server already running.
at com.sun.enterprise.iiop.POAProtocolMgr.initializeNaming(POAProtocolMg
r.java:134)
at com.sun.enterprise.server.J2EEServer.run(J2EEServer.java:227)
at com.sun.enterprise.server.J2EEServer.main(J2EEServer.java:918)
java.lang.RuntimeException: Could not initialize j2ee server. Possible cause cou
ld be another instance of the server already running.
at com.sun.enterprise.server.J2EEServer.run(J2EEServer.java:355)
at com.sun.enterprise.server.J2EEServer.main(J2EEServer.java:918)
J2EE server reported the following error: Could not initialize j2ee server. Poss
ible cause could be another instance of the server already running.
Error executing J2EE server ...
G:\jmseg\simple>I got exactly the same message when I tried to start j2ee server... It worked fine the second time round though, So I suggest you try it again.
tim.. -
Failed update is doing rollback, but not exiting.
Hi ,
I have written some update FM.I am doing this based on the records(1 to many) in the table parameter.
The requirement is,during the updation if any error happens,I need to rollback the work and need to stop the further processing.As of now,it is roll backing the work.
But it is going to the next line.I have used 'EXIT' statement in my pgm.
Please suggest me a solution.
Thanx,
Selva
Edited by: Julius Bussche on Dec 15, 2008 11:04 AMHi,
Let us assume there is a header and an Item table and that the header table is the check table for the item table.
So
lt_header type standard table of header_table,
lt_item type standard table of item_table.
Assume all data is in and you are ready for updation.
insert header_table from tablelt_header.
if sy-subrc eq 0.
insert item_table from lt_item.
if sy-subrc eq 0.
commit work and wait.
else.
rollback work.
perform issue_error_message_to_user.
else.
perform issue_error_message_to_user.
endif.
I have written this code in this reply only. Please use proper syntax as required. I just shared the concept i had in mind.Please Check and tell -
JMS adapter transaction. Rollback message to queue.
Hi all !
A have question about jms adapter transaction. My composite application has 3 steps : JMS adapter (listener), mediator, WS adapter. JMS adapter listen queue push message to mediator, mediator invoke web service. If ws not available (server down), mediator try recovery 5 times. After 5 times, reject message from queue. I wont rollback message to queue. I saw examples with JMS + BPEL, but it not help me. Anybody can help me.Hi,
You don’t need to catch a mediator fault – you can let it rollback to the JMS Queue and let the Queue do the retries.
To get the retries working, log in to the weblogic console and navigate to JMS Modules -> Your Module -> Your Queue -> Configuration -> Delivery Failure
Here you will find options for Redelivery Limit. Set this to the number of retries you need.
Then navigate to the connection factory you want and set the redelivery delay.
This should get your desired behaviour, but once the message has failed it will be discarded. If you prefer to put it on an error queue you can create an error queue, and in the original queue’s, goto Delivery Failure, change the expireation policy and set the Error Destination to be your error queue.
Hope that helps!
Robert -
JMS bridge and MQSeries. looking for statistics
Hi !
I have to use Weblogic 7 SP4 in cluster with a distant MQSeries queue manager.
I know I can't have a "exactly once" quality of service. I use a MDB (deplyed
on each instance of the server).
I'm looking for statistics about how often a message can be treated 2 (or more)
times.
Thanks a lot for any help !
Florent
Hi Florent,
Since these are MQ messages, it might be possible to find
such statistics in MQ. Also, I think that MQ stores a
redelivery count in their messages - so you can likely
instrument your application code to get at the count.
Note that 7.0 actually does support exactly once with WL MDBs driven
by MQ. If you use transactions you can infer some stats on redeliveries
by checking the relevant transaction statistics for rollback counts.
I'm attaching some notes on JMS integration for your
convenience.
Tom
florent wrote:
> Hi !
>
> I have to use Weblogic 7 SP4 in cluster with a distant MQSeries queue manager.
> I know I can't have a "exactly once" quality of service. I use a MDB (deplyed
> on each instance of the server).
>
> I'm looking for statistics about how often a message can be treated 2 (or more)
> times.
>
> Thanks a lot for any help !
>
> Florent
JMS Integration of Foreign Vendors with BEA WebLogic Server
The following notes are derived mostly from "http://dev2dev.bea.com/technologies/jms/index.jsp".
For additional questions, a good forum for WebLogic questions in general is "newsgroups.bea.com". These can be mined for information by using Google's newsgroup search function.
JMS Integration Overview
- For integration with "non-Java" and/or "non-JMS" platforms, see "Non-Java Integration Options" below.
- For a foreign JMS vendor to participate in a WL transaction it must support XA. Specifically, it must support the javax.jms.XA* interfaces.
- In WL versions 6.0 and up it is possible to make synchronous calls to foreign JMS vendors participate in a WL transaction as long as the foreign vendor supports XA.
- WL 6.0 and 6.1 MDBs can be driven by foreign vendors non-transactionally. They can be driven transactionally by a select few foreign vendors (MQ is not part of the select few)
- WL 7.0 and later, MDBs can be driven by foreign vendors transactionally and non-transationally.
- WL 6.1 and later WL provides a messaging bridge feature. Messaging bridges forward messages between any two JMS destinations, including foreign destinations, and can transfer messages transactionally or non-transactionally.
- WL 8.1 JMS provides additional features that simplify transactional and JNDI integration of foreign vendors. See http://edocs.bea.com/wls/docs81/jms/intro.html#jms_features
Integration with 8.1 Details
A good overview of 8.1 JMS interop capability is the presentation "Integrating Foreign JMS Providers with BEA WebLogic Server" here:
http://www.bea.com/content/files/eworld/presentations/Wed_03_05_03/Application_Servers/1097-Foreign_JMS_Providers_WLS.pdf
This document refers to helpful new 8.1 features, which simplify integration. These include:
http://edocs.bea.com/wls/docs81/ConsoleHelp/jms_config.html#accessing_foreign_providers
http://edocs.bea.com/wls/docs81/jms/j2ee_components.html#1033768
And are also summarized here (under interoperability):
http://edocs.bea.com/wls/docs81/jms/intro.html#jms_features
Also read the extensive MDB documentation, which extensively covers integrating foreign vendors:
http://edocs.bea.com/wls/docs81/ejb/message_beans.html
The 8.1 features are likely sufficient for most 8.1 integration needs, and you may not need to refer "Using Foreign JMS Providers With WLS" white-paper mentioned below.
Integration with 6.1 and 7.0 Details
Read the "Using Foreign JMS Providers With WLS" white-paper:
http://dev2dev.bea.com/products/wlserver/whitepapers/jmsproviders.jsp
Note that this white-paper does not take into account 8.1 features.
For 7.0 read the extensive 8.1 MDB documentation, which largely also applies to 7.0:
http://edocs.bea.com/wls/docs81/ejb/message_beans.html
Non-Java Integration Options
- WL JMS has a JNI based C client which is available for Windows and some UNIX platforms. This C client supports 7.0 and up, and will be officially packaged with WLS in 9.0 (virtually unchanged). The C API is currently only supported through the jms newsgroup. See "JMS C API", here:
http://dev2dev.bea.com/technologies/jms/index.jsp
- WL supports direct Windows COM access through its "JCOM" feature. This doesn't include the JMS API, but one can invoke EJBs which in turn invoke JMS. See
http://e-docs.bea.com/wls/docs61/jcom.html
http://e-docs.bea.com/wls/docs70/jcom/
http://e-docs.bea.com/wls/docs81/jcom/
- Similar to JCOM, but more advanced, WL supports IIOP standard based access on multiple platforms. You can use the BEA Tuxedo C client for this purpose (no license fee). This doesn't include the JMS API, but one can invoke EJBs which in turn invoke JMS. See
http://e-docs.bea.com/wls/docs81/rmi_iiop/
http://e-docs.bea.com/wls/docs70/rmi_iiop/
http://e-docs.bea.com/wls/docs61/rmi_iiop/
Unlike most other approaches, the IIOP client approach also allows the client to begin and commit user (JTA) transactions (not configured).
- If you already have a BEA Tuxedo license, one option is communicate through BEA Tuxedo (which has various APIs on Windows) and configure a WebLogic Server to respond to these requests via the WTC bridge. Search for "WTC" in the BEA docs. Unlike most other approaches, the Tuxedo API approach also allows the client to begin and commit user (JTA) transactions.
- Another approach is to interop via web-service standards. Or even to simply to invoke a servlet on the WL server using a basic HTTP call from Windows. These in turn can invoke the JMS API. There is a white-paper on "Interoperability Study of BEA WebLogic Workshop 8.1 and Microsoft .NET 1.1 Web Services", that demonstrates web-services here:
http://ftpna2.bea.com/pub/downloads/WebLogic-DotNet-Interop.pdf
- Yet another approach is to use a third party product that is designed to wrap any JMS vendor. There are even open source versions. In no particular order, here are some examples: Open3 WinJMS, CodeMesh, Active JMS, SpiritSoft
- Finally, there are .NET/C/C++ integration libraries that not specific to JMS, some examples are JNBridge, Jace, and CodeMesh.
Notes on MQ Remote Capable XA Clients
Until recently, IBM MQ JMS clients could not work transactionally unless they were running on the same host as their MQ server. This is a limitation unique to MQ that was relaxed with the introduction of IBM's new "WebSphere MQ Extended Transactional Client". See:
http://publibfp.boulder.ibm.com/epubs/pdf/csqzar00.pdf
The product is new, and for some reason, configuration of this client seems to be tricky, even when WebLogic is not involved at all. Oddly, the main sticking point seems to be simply making sure that class paths refer to the required IBM jars:
- Required on WLS where MQ objects are bound into JNDI:
com.ibm.mq.jar, com.ibm.mqjms.jar
- Required only if MQ objects are bound into JNDI on a different server:
com.ibm.mq.jar
If there are problems when using this client, first get it to work using a pure IBM client without any BEA classes involved. Once that is working, search the WL JMS newsgroup for answers and/or contact BEA customer support.
Notes on Oracle AQ Integration
If problems are encountered integrating Oracle's built-in queuing (Oracle AQ) JMS client, there is publicly available wrapper code that can aid integrating AQ directly into MDBs, JMS, or the messaging bridge. The solution is titled "Startup class to bind AQ/Referenceable objects to WLS JNDI", is not supported by BEA, and is posted to:
http://dev2dev.bea.com/codelibrary/code/startupclass.jsp
Caveats:
The solution doesn't directly support concurrent consumers. Perhaps Oracle requires that concurrent consumers each have a unique JMS connection? As a work-around, parallel message processing can be achieved indirectly by forwarding AQ messages into a WL JMS destination - which do support concurrent processing.
Up-to-date versions of Oracle may be required. For more information, google search the weblogic.developer.interest.jms newsgroup for "Oracle" and "AQ".
The solution doesn't seem to support transactions, it may be possible to extend it to do so.
MDB Thread Pool Notes
WL7.0SP? and WL8.1 and later support the "dispatch-policy" field to specify which thread pool an MDB uses to run its instances. In most cases this field should be configured to help address potential performance issues and/or dead-locks:
http://edocs.bea.com/wls/docs81/ejb/DDreference-ejb-jar.html#dispatch-policy
(Note that "dispatch-policy" is ignored for non-transactional foreign vendors; in this case, the MDB "onMessage" callback runs in the foreign vendor's thread.)
MDB Concurrency Notes
Queue MDBs driven by foreign providers can run multiple instances concurrently. Topic MDBs driven by foreign providers are limited to one instance (not sure, but transactional foreign driven topic MDBs may not have this limitation). The size of the thread pool that the MDB runs in and the "max-beans-in-free-pool" descriptor limit how many instances run concurrently.
Design Guide-Lines and Performance Tuning Notes
The "WebLogic JMS Performance Guide" white-paper contains detailed design, performance, and tuning information for Clustering, Messaging Bridge, JMS, and MDBs.
http://dev2dev.bea.com/products/wlserver/whitepapers/WL_JMS_Perform_GD.jsp
-
Redelivery of messages in JCAPS + WebSphere App Server
I have a POJO that runs on WebSphere Application Server 6.1 and connects to a JCAPS 5.1.X queue using JMS API. JCAPS has been configured as a 'Generic JMS provider' in WebSphere and the queues and QCFs configured via WAS' admin console. The POJO is picking the messages and processing it just fine.
Now while processing the message, in case of failures, I need to reprocess the message 'n' number of time after a certain delay and move it to a DLQ if all attempts fail, which from my understanding is standard JMS stuff. Reading through the JCAPS documentation it appears that it does support this.
My question is how would I configure these details in WebSphere's JMSProvider/QCF/Q configuration. I have tried adding these as 'custom properties' of QCF in admin console, but that did not work:
JMSJCA.redeliveryhandling=5:1000;10:5000;50:move(qu eue:mydlq)
redeliveryhandling=5:1000;10:5000;50:move(queue:myd lq)
This the code snippet from the POJO that receives the events:
while (count > 0) {
queueSession = queueConnection.createQueueSession(true, -1);
controlQueue = getQueue(QUEUE_NAME, queueSession);
queueReceiver = queueSession.createReceiver(controlQueue);
queueConnection.start();
TextMessage message = (TextMessage) queueReceiver.receive();
count--;
System.out.println("EventReceiver "
+"Received synchronize message; "+ message.getText()
+" expect "+ count + " more");
//If the message body has "throw" in it then roll it back. The
//message should go back to the queue and then be redelivered by
//the JMS Provider.
if ("throw".equals(message.getText())) {
queueSession.rollback();
} else {
queueSession.commit();
}Any help would be greatly appreciated.
PS: The code snippet is from an example I found somewhere on the web.My knowledge is that if you want to make use of those specific JMSJCA features you need to deploy the RA, configure a connection pool and consume messages through a MDB, not a POJO. I don't know how your POJO is getting the JMS connection, but I doubt is using any RA feature this way, as it is not the JMSJCA RA which is actually handling your connections. These are just my 5 cents, maybe you could ask more specific JMSJCA questions to their mailing list.
-
Message-driven bean problem (re-delivering of JMS msg)
Sorry for crossposting this (already posted in JMS forum), but perhaps someone here (who doesn't read JMS forum) knows the answer to this problem - it's basically a JMS problem, but closely related to EJB:
I browsed through all available docs but found no answer to this question: How can I force the re-delivery of a JMS message to happen in a few minutes instead of immediately?
I use JMS in an EJB container (SonicQ in Borland Enterprise Server 5.0.1) and messages are consumed by a message-driven bean. The problem arises when the bean sets the transaction in which the onMessage() function is called to rollback-only: Then, the message is redelivered immediately again causing an infinte processing loop and 100% CPU load on the machine until the message is finally consumed.
Is it possible to set a timeout for such a "temporarily rejected" message so that it is retries in a few minutes? Would that be a programming issue, or a configuration issue of the container and/or JMS?Hi Chranq,
What you are talkin about is a container configuration thing as far as I can figure out. I may be that your JMS implementation doesn't support it.
/Stig -
I am cross posting to transaction & jms, sorry if this is a mistake...
We have a setup where JMS messages are published to a topic. The posting is transacted
(XA) and is a consequence of a CMP update so JMS and JDBC (Oracle OCI) cooperate
to commit, or not.
Most of the time, transactions issue just a few JMS messages but at least once
a day, we issue hundred of thousands of such messages (max has been about 600000
but typically 300000).
Our setup is four instances of Weblogic 6.1SP3 (two clustered, two not), the topic
is on one of them (all 3 other servers connect to that instance to publish) and
we have a couple MDBs deployed only on the instance that has the JMSServer and
they all listen to the local topic. The transactionnal settings of these MDBs
is CMT and XA (because the beans will write to the DB). Furthermore, these MDB
have been setup to be durable. One of these is just a logger MDB with 20 instances
max.
It worked fine for a couple weeks but we have been running into problems for the
past two days. All of a sudden, the server no longer responds to weblogic.ADMIN
PING. The server log indicates the following error repetitively (MB of logs just
of this)
####<13 nov. 03 23:15:41 CET> <Alert> <JMS> <XXXXXXX> <send1> <ExecuteThread:
'32' for queue: 'default'> <> <> <040060> <JMSServer "OutputServerSend1", unhandled
exception during rollback, java.lang.NullPointerException.>
java.lang.NullPointerException
at weblogic.jms.backend.BEDurableTopicMessageInfo.rollbackReceiveTran(BEDurableTopicMessageInfo.java:352)
at weblogic.jms.backend.BEXATranEntrySubscribe.startRollback(BEXATranEntrySubscribe.java:145)
at weblogic.jms.backend.BEXATranEntry.execute(BEXATranEntry.java:127)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
The logger MDB seems to have started processing the JMS messages. This means that
the transaction that included the JMS message publishing must have commited. Unfortunatly,
there are only 20 log lines before the server restart, so the server must have
hanged although it did commit the messages processed by the logger since the log
messages are apparently not repeated. I have no idea why. I think this is coherant
with the fact that exception above seems to relate to subscribers.
When we restart the server, the topic gets purged and seem to be processed (we
have not found a way to verify that each message has been processed but it's looking
good)
Any ideas ?
Thanks
Philippe
I am cross posting to transaction & jms, sorry if this is a mistake...
We have a setup where JMS messages are published to a topic. The posting is transacted
(XA) and is a consequence of a CMP update so JMS and JDBC (Oracle OCI) cooperate
to commit, or not.
Most of the time, transactions issue just a few JMS messages but at least once
a day, we issue hundred of thousands of such messages (max has been about 600000
but typically 300000).
Our setup is four instances of Weblogic 6.1SP3 (two clustered, two not), the topic
is on one of them (all 3 other servers connect to that instance to publish) and
we have a couple MDBs deployed only on the instance that has the JMSServer and
they all listen to the local topic. The transactionnal settings of these MDBs
is CMT and XA (because the beans will write to the DB). Furthermore, these MDB
have been setup to be durable. One of these is just a logger MDB with 20 instances
max.
It worked fine for a couple weeks but we have been running into problems for the
past two days. All of a sudden, the server no longer responds to weblogic.ADMIN
PING. The server log indicates the following error repetitively (MB of logs just
of this)
####<13 nov. 03 23:15:41 CET> <Alert> <JMS> <XXXXXXX> <send1> <ExecuteThread:
'32' for queue: 'default'> <> <> <040060> <JMSServer "OutputServerSend1", unhandled
exception during rollback, java.lang.NullPointerException.>
java.lang.NullPointerException
at weblogic.jms.backend.BEDurableTopicMessageInfo.rollbackReceiveTran(BEDurableTopicMessageInfo.java:352)
at weblogic.jms.backend.BEXATranEntrySubscribe.startRollback(BEXATranEntrySubscribe.java:145)
at weblogic.jms.backend.BEXATranEntry.execute(BEXATranEntry.java:127)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
The logger MDB seems to have started processing the JMS messages. This means that
the transaction that included the JMS message publishing must have commited. Unfortunatly,
there are only 20 log lines before the server restart, so the server must have
hanged although it did commit the messages processed by the logger since the log
messages are apparently not repeated. I have no idea why. I think this is coherant
with the fact that exception above seems to relate to subscribers.
When we restart the server, the topic gets purged and seem to be processed (we
have not found a way to verify that each message has been processed but it's looking
good)
Any ideas ?
Thanks
Philippe
-
JMS Adapter Tuning in Oracle 10G SOA suite - Fixing the Errors
Hi All,
We are getting an error in Production environment while a BPEL process producing (enqueue) a message to a JMS queue by using JMS adapter. (partener link)
The error is as follows.
Adapter Framework unable to create outbound JCA connection.
file:/sw/appnew/product/SOA/10.1.3/bpel/domains/default/tmp/.bpel_CurrenListJMSProducer_1.0_4ec528ec93a8a6ff0278fab9701dcc71.tmp/CurrenListJMSProducerV1.wsdl [ Produce_Message_ptt::Produce_Message(OutputParameters) ] - : The Adapter Framework was unable to establish an outbound JCA connection due to the following issue: oracle.j2ee.connector.proxy.ProxyInterceptException: javax.resource.ResourceException: RollbackException: Transaction has been marked for rollback: null [Caused by: RollbackException: Transaction has been marked for rollback: null]
Please note that we are not getting this error every time, few BPEL instances are getting this error, around 3 out of 10 instances.
We are using Orcacle 10G SOA suite.
The BPEL process will take the messages from Oracle Apps adapter and send to the JMS queue, where we are getting error.
I can see in the BPEL.xml the "retryInterval" property set to '60' for both partner links (Apps adapter and JMS adapter).
But not set any other values. So,these values may be default.
We need to fix this issue soon.
I am requesting you all the Experts and Gurus, please let me know what can be done to fix this issue.
Thanks a lot in advance,
John.Hi All,.
Is there any work around for the above issue?
I tried all the below JMS tunings, but not no improvement.
<property name="useJCAConnectionPool">true</property>
<property name="maxSizeJCAConnectionPool">500</property>
<property name="retryMaxCount">10</property>
<property name="retryInterval">60</property>
Please let
me know if any other logs or any other information is required in order to analyse the issue.
Thanks,
John -
Spring and Jms message: no message in the queue
Hi all,
this is my application
Spring 3.0.5 + Oc4j 10.1.3.3 + Oracle DB + Oracle Aq
This is the flow:
1. Update datas
2. Send jms message
The application updates correctly datas, in the same transaction sends a message to an oracle jms queue but the queue table is empty.
Transaction starts with method avvService.updateStatoService()
This is a log snapshot
2013-02-07 11:04:48,982 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:365) CLIENT: HOST: - Creating new transaction with name [it.mycompany.gevi.service.avvenimenti.AvvenimentoService.updateStatoAvvenimentoService]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
2013-02-07 11:04:52,340 [DEBUG] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO.updateService - getStatement
2013-02-07 11:04:52,340 [INFO] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO - SQL is:
UPDATE TABLE_NAME
SET STATO = ?
WHERE COD = ?
2013-02-07 11:04:52,918 [INFO] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO - {1=1, 2=1200300146}
2013-02-07 11:04:52,949 [INFO] it.mycompany.gevi.service.GenericService.updateService(GenericService.java:50) CLIENT: HOST: - Risultato updateService:1
2013-02-07 11:04:52,965 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:470) CLIENT: HOST: - Participating in existing transaction
2013-02-07 11:04:53,730 [DEBUG] org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:464) CLIENT: HOST: - Executing callback on JMS Session: oracle.jms.AQjmsSession@ee2a92
2013-02-07 11:04:54,167 [DEBUG] org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:567) CLIENT: HOST: - Sending created message: oracle.jms.AQjmsTextMessage@27fdb9
2013-02-07 11:04:54,526 [INFO] it.mycompany.gevi.service.JMSSenderService.sendMessage(JMSSenderService.java:64) CLIENT: HOST: - JSM Message Sent!
2013-02-07 11:04:54,526 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:752) CLIENT: HOST: - Initiating transaction commit Spring bean configuration file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:orcl="http://www.springframework.org/schema/data/orcl"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/data/orcl
http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"
default-lazy-init="true" default-autowire="byName">
<jee:jndi-lookup id="geviDs" jndi-name="jdbc/DBGeviDS" />
<jee:jndi-lookup id="geviAqAdmDs" jndi-name="jdbc/AQAdmGeviDS" />
<orcl:aq-jms-connection-factory id="topicConnectionFactory" data-source="geviAqAdmDs"
connection-factory-type="TOPIC_CONNECTION" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="sessionTransacted" value="true"/>
<property name="connectionFactory" ref="topicConnectionFactory"/>
<property name="explicitQosEnabled" value="true"/>
<property name="timeToLive" value="60000"/>
<property name="pubSubDomain" value="true"/>
<property name="defaultDestinationName" value="VR_INFO_VAR_TOPIC"/>
</bean>
<tx:jta-transaction-manager/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<aop:config>
<aop:pointcut id="genericServiceMethods" expression="execution(* it.mycompany.gevi.service..*Service.*(..))" />
<aop:advisor pointcut-ref="genericServiceMethods" advice-ref="txServiceAdvice"/>
</aop:config>
<tx:advice id="txServiceAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="read*Service" read-only="true"/>
<!-- Other methods use the default transaction settings (see below) -->
<tx:method name="insertReturning*Service" propagation="REQUIRED" />
<tx:method name="create*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="delete*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="update*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="sendMessage" propagation="REQUIRED" rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
<bean name="genericService" class="it.mycompany.gevi.service.GenericService" />
<bean name="avvService" class="it.mycompany.gevi.service.avvenimenti.AvvenimentoService"/>
<bean name="jmsSender" class="it.mycompany.gevi.service.JMSSenderService" >
<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>
</beans>Thanks in advance.Hi all,
this is my application
Spring 3.0.5 + Oc4j 10.1.3.3 + Oracle DB + Oracle Aq
This is the flow:
1. Update datas
2. Send jms message
The application updates correctly datas, in the same transaction sends a message to an oracle jms queue but the queue table is empty.
Transaction starts with method avvService.updateStatoService()
This is a log snapshot
2013-02-07 11:04:48,982 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:365) CLIENT: HOST: - Creating new transaction with name [it.mycompany.gevi.service.avvenimenti.AvvenimentoService.updateStatoAvvenimentoService]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,-java.lang.Exception
2013-02-07 11:04:52,340 [DEBUG] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO.updateService - getStatement
2013-02-07 11:04:52,340 [INFO] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO - SQL is:
UPDATE TABLE_NAME
SET STATO = ?
WHERE COD = ?
2013-02-07 11:04:52,918 [INFO] it.mycompany.service.qbuilder.logic.QBUpdateService.doExecute(QBUpdateService.java:62) CLIENT: HOST: - DAO - {1=1, 2=1200300146}
2013-02-07 11:04:52,949 [INFO] it.mycompany.gevi.service.GenericService.updateService(GenericService.java:50) CLIENT: HOST: - Risultato updateService:1
2013-02-07 11:04:52,965 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:470) CLIENT: HOST: - Participating in existing transaction
2013-02-07 11:04:53,730 [DEBUG] org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:464) CLIENT: HOST: - Executing callback on JMS Session: oracle.jms.AQjmsSession@ee2a92
2013-02-07 11:04:54,167 [DEBUG] org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:567) CLIENT: HOST: - Sending created message: oracle.jms.AQjmsTextMessage@27fdb9
2013-02-07 11:04:54,526 [INFO] it.mycompany.gevi.service.JMSSenderService.sendMessage(JMSSenderService.java:64) CLIENT: HOST: - JSM Message Sent!
2013-02-07 11:04:54,526 [DEBUG] org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:752) CLIENT: HOST: - Initiating transaction commit Spring bean configuration file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:orcl="http://www.springframework.org/schema/data/orcl"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/data/orcl
http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd"
default-lazy-init="true" default-autowire="byName">
<jee:jndi-lookup id="geviDs" jndi-name="jdbc/DBGeviDS" />
<jee:jndi-lookup id="geviAqAdmDs" jndi-name="jdbc/AQAdmGeviDS" />
<orcl:aq-jms-connection-factory id="topicConnectionFactory" data-source="geviAqAdmDs"
connection-factory-type="TOPIC_CONNECTION" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="sessionTransacted" value="true"/>
<property name="connectionFactory" ref="topicConnectionFactory"/>
<property name="explicitQosEnabled" value="true"/>
<property name="timeToLive" value="60000"/>
<property name="pubSubDomain" value="true"/>
<property name="defaultDestinationName" value="VR_INFO_VAR_TOPIC"/>
</bean>
<tx:jta-transaction-manager/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<aop:config>
<aop:pointcut id="genericServiceMethods" expression="execution(* it.mycompany.gevi.service..*Service.*(..))" />
<aop:advisor pointcut-ref="genericServiceMethods" advice-ref="txServiceAdvice"/>
</aop:config>
<tx:advice id="txServiceAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="read*Service" read-only="true"/>
<!-- Other methods use the default transaction settings (see below) -->
<tx:method name="insertReturning*Service" propagation="REQUIRED" />
<tx:method name="create*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="delete*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="update*Service" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="sendMessage" propagation="REQUIRED" rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
<bean name="genericService" class="it.mycompany.gevi.service.GenericService" />
<bean name="avvService" class="it.mycompany.gevi.service.avvenimenti.AvvenimentoService"/>
<bean name="jmsSender" class="it.mycompany.gevi.service.JMSSenderService" >
<property name="jmsTemplate" ref="jmsTemplate"/>
</bean>
</beans>Thanks in advance. -
JMS - UserTransaction - Commit issue
Introduction
I am moving from WebSphere to Weblogic and have counterd an UserTransaction commit issue.
The code have not been modified, however the logic in Weblogic and Websphere behaves different.
The messagingsystem is Websphere MQ, in Weblogic I have QCF, destinations, host and port etc. in a .bindings file, and I have configured JMS server and JMS modules with corresponding jndi names.
I have verified that this configuration is correct throug a custom develop testtool deployed in WL, message is sent successfully to MQ.
The problem - description
However in my application i'm using UserTransaction and this is not working as expected.
I have two classes that communicate with MQ (AbcDAO.java and QueueBroker.java) AbcDAO.java creates a UserTransaction and communicates with Queuebroker throug a method called "SendToAutoS" this method retrives the corrilationId (for the message sendt to MQ) from Queuebroker.
The SendMessage method creates qcf, queueconnection, queue etc and sends the message to MQ. When i debug this steps (line:queueSender.send(theMessage) I can verify in MQ that a message count is registerted in mq on the correct queue, but it's not shown (since its not commited). However when performing finalize in Queuebroker, which close both session and connection, the messagecount is gone in MQ, and when returing to AbcDAO.java to perform ut.commit(); there is not any message on Queue.
For me it looks like the message is rolledback when session and connection closes.
Actions tried
If I change this line QueueBroker , transacted to false witch i understand sends message without the need to commit:
boolean transacted = false;
queueSession = queueConnection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE);
the message is sendt successfully to MQ. However now either commit or rollback on the UserTransaction is working with transacted=false.
I need the commit and rollback to be done on the UserTransaction for my application.
Anyone have an idea why this is not working?
The files - content
AbcDAO.java - that creates a usertransaction
ut = ServiceLocator.getInstance().getUserTransaction();
ut.begin();
msgCorId = sendToAutoS(userVO, messageSend, transactionQeueSend, transactionQeueFactory);
ut.commit();
//SendToAutoS - that calls the Queuebroker method - sendMessage
private String sendToAutoS(UserVO userVO, String message, String transactionQueue, String transactionQueueFactory) throws DaoException {
try {
log.debug("..");
return QueueBroker.getInstance().sendMessage(message, transactionQueue, transactionQueueFactory);
} catch (BrokerException be) {
log.error("BrokerException", be);
QueueBroker.java - that sends the message to MQ
public String sendMessage(String message, String transactionQueue, String transactionQueueFactory) throws BrokerException {
try {
// Get service locator
ServiceLocator sl = ServiceLocator.getInstance();
// Create QueueConnectionFactory with help form service locator
queueConnectionFactory = (QueueConnectionFactory) sl.getQueueConnectionFactory(transactionQueueFactory);
// Create QueueConnection
queueConnection = queueConnectionFactory.createQueueConnection();
// Create QueueSession, transacted - client has to commit !
boolean transacted = true;
queueSession = queueConnection.createQueueSession(transacted, QueueSession.AUTO_ACKNOWLEDGE);
// Create queue with help from service locator
queue = (Queue) sl.getQueue(transactionQueue);
// Create QueueSender
queueSender = queueSession.createSender(queue);
// Create message and sent it
Message theMessage = null;
theMessage = queueSession.createTextMessage(message);
// Log time
long time = System.currentTimeMillis();
// Set log time on message
theMessage.setJMSTimestamp(time);
// Send
queueSender.send(theMessage);
queueSender.close();
// Return unique messageID for message just been sent
return theMessage.getJMSMessageID();
} catch (JMSException je) {
BrokerException ex = new BrokerException();
ex.setMessageKey("requisition.jms.broker.queue");
Object[] o = {"SEND", "String to Autosys = " + message};
ex.setMessageArgs(o);
ex.setRootCause(je);
throw ex;
} catch (ServiceLocatorException e) {
BrokerException ex = new BrokerException();
ex.setMessageKey(e.getMessageKey());
ex.setMessageArgs(e.getMessageArgs());
ex.setRootCause(e.getRootCause());
throw ex;
} finally {
// Clean up - close connection and session if exist
if (queueConnection != null) {
finalize();
* Finalize queue handling
* @throws BrokerException e
protected void finalize() throws BrokerException {
try {
// Close connections
queueSession.close();
queueConnection.close();
} catch (JMSException je) {
BrokerException ex = new BrokerException();
ex.setMessageKey("requisition.jms.broker.queue");
Object[] o = {"FINALIZE", "Close connections" };
ex.setMessageArgs(o);
ex.setRootCause(je);
throw ex;
Edited by: reZer on 14.sep.2011 13:05
Edited by: reZer on 14.sep.2011 13:06I know you are trying to send a JMS message, but just because this is true the generic JMS forum is not automatically the place you should ask questions like this. Your real beef is with the container you are using (Weblogic), UserTransaction and persistent JMS messages in combination with the specific JMS provider you are using.
You will have far more chance to get help with this problem if you ask it in the Weblogic forum which you can also find on this very website. If you make a new post, be sure to create a link to it here so people can follow it.
https://forums.oracle.com/forums/category.jspa?categoryID=193
And perhaps more specific:
WebLogic Server - JMS -
I have a usecase as below -
jms.Q1 (nonxa) -- [ proxy service -- publish to a jms.Q2 (xa) -- raise an error ]
A proxy service receives request from non-xa queue (Q1) ,
then the proxy service publish that message to another queue (Q2) via XA enabled business service (i use connection factory as XA) ,
then i raise an error in the message flow.
What i need is, I want to rollback the message which i published to "Q2" once i raise an error in message flow.
Can anyone please help me out whether this is possible by using any of the routing option,etc..?
Regards
SeshaConfigure these:
1. Enable the option Same Transaction For Response in the Proxy Service configuration.
2. Use QoS as Exactly Once in the publish action which calls the JMS business service.
3. Use XA connection factory for connection between businsss service and target JMS Queue
4. Make sure that the error reaches System Error Handler. To ensure this you need to make sure that the flow does not encounter any Reply action after the Raise Error action you have configured in the message flow.
Once you configure like above:
1. Message will be deleted from source queue as soon as OSB Proxy picks up the message (since this is not XA enabled)
2. Message will be published to target JMS queue but not committed till the message flow is completed. So it can rollback in case there is an error after the publish action.
3. If based on a condition a Raise error action is executed (or any other error happens in the flow) message will be rolled back from target queue in case the error reaches the System Level error handler. So message will not be present in neither source queue nor the target queue. -
i have an MDB deployed on weblogic 8.1 sp6 server. My confusion here is how the MDB handles transaction rollbacks. E.g suppose if the MDB is designed to do the below action.
1) read an xml message from a jms queue
2) insert some database records
3) generate some xml message, post it to some other jms queue
suppose if step 1 and 2 is completed, and its on step 3, at this point weblogic server shutdowns suddenly, once i restart the server, it reads the xml message again from the jms queue, but this time it errors out, because it finds the data already entered in step 2.
My question is when the weblogic server shut down while the mdb was at step 3, why didnt it removed all the db entries it made in step 2. This behaviour apears to me as partial rollback. I have given the mdb descriptor below.
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>CSS_Response</ejb-name>
<ejb-class>com.bt.neo.core.utility.appcontroller.transport.mdb.JmsMessageReceiver</ejb-class>
<transaction-type>Container</transaction-type>
<acknowledge-mode>auto-acknowledge</acknowledge-mode>
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
</message-driven-destination>
<env-entry>
<env-entry-name>ejb/BeanFactoryPath</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>core-css-response-inbound.xml</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>ProcessorBeanName</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>transportAdaptor</env-entry-value>
</env-entry>
<resource-ref>
<res-ref-name>jms/faultTo</res-ref-name>
<res-type>javax.jms.Destination</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>CSS_Response</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>
</ejb-jar>Please clear my doubt.
Edited by: Deepak Dev on 19-Dec-2011 11:01General information on message-driven beans can be found here: http://docs.oracle.com/cd/E12840_01/wls/docs103/ejb/message_beans.html
To transaction configuration is discussed here: http://docs.oracle.com/cd/E12840_01/wls/docs103/ejb/message_beans.html#wp1162058
Looks like you have to set the transaction-type to Container and the trans-attribute to required. Also see the note:
- However, if you make this configuration error, the MDB will not run transactionally—if a failure occurs mid-transaction, updates that occurred prior to the failure will not be rolled back.
Maybe you are looking for
-
How to add a playlist folder to your iPhone manually so the music can be organized in separate folders (playlists). It's supposed to be simple and intuitive in Apple but I spent few hours trying to figure it out in my iTunes/searching in internet a s
-
Issue in Return sales, condition value calculation.
Hello All, I am creating return sales order (order type-RE) with reference to a Billing document, and reducing the quantity while creating the sales order (Example: Ref billing quantity-60 and sales order quantity-30). Here even though the quan
-
Execute javascript with input parameters of a taskflow
Using JDev 11g PS4 I have a taskflow that uses some javascript. When the taskflow has been loaded, I need to execute a javascript function that uses 2 input parameters of my taskflow. I don't really know how I can execute the javascript with my input
-
So as usual, I updated the software on My mac and laptop... it is version 10,6.8 and now my mail applications Version: 4.6 won't open. Says it is the wrong version to work with the software... this is the FIRST time I am unhappy with my Apple product
-
Business Area should be defined
Hi I proposed that each location (branches) of my client should be defined as an profit center (for getting trial balance at business area level). But my client is insisting for creating location as a business area and not profit center. But i think