 <p>Consider <a href="http://blog.pasker.net/2010/10/21/use-jdbc-jms-without-jta/" rel="nofollow">1.5 phase commit</a>. Basically:</p> <ul> <li>step 1: You commit the DB transaction</li> <li>step 2: You commit the JMS transaction.</li> </ul> <p>Possible error scenarios: </p> <ol> <li>DB transaction fails.</li> <li>DB transaction sucessful JMS transaction fails.</li> <li>all successful.</li> </ol> <p>Not 1, nor 3 leaves your system in inconsistent state. In case of 1, you just need to resend the message.</p> <p>To handle scenario 2. you need to introduce duplicate check to your system. So essentially your transaction management would look like similar to this:</p> <pre><code>//pseudo code if (isDublicate(message)) commitJMSTransaction(); else doYourBusinessLogic(); doYourDBOperation(); commitDBTransaction(); commitJMSTransaction(); </code></pre> <p>If the JMS transaction fails your message broker will retry to send the message (or you need to resend it manually depending on your broker setup) but you duplicate check will detect it and remove it from the queue.</p>