Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Summarizing your question: You're looking for a transactionally-safe way to send messages.</p> <h2>Option 1: JMS</h2> <p>Transactionally safe messaging is exactly what JMS is for. There's also good JMS integration in Spring, See the <a href="http://static.springsource.org/spring/docs/3.0.x/reference/jms.html" rel="noreferrer">JMS chapter</a> in the Spring documentation.</p> <p>That will make sure that the messages are sent <em>if and only if</em> the transaction is committed. It also helps for dealing with errors in listeners for these events.</p> <p>A difference with your current setup is that these events will be handled asynchronously: your service will return before these events have been handled. (JMS will make sure that they are processed eventually, it can be configured to try multiple times and how to deal with errors,...). Depending on your needs, that may be a good or a bad thing.</p> <h2>Option 2: Transaction synchronization</h2> <p>Alternatively, if JMS is too <em>heavy-weight</em> for your case, you could use transaction synchronization: When sending an event, instead of sending it directly use Spring's <code>TransactionSynchronizationManager.registerSynchronization</code>, and send the message in the <code>afterCommit()</code> of your <code>TransactionSynchronization</code>. You could either add a new synchronization per event to be sent, or add one synchronization and keep track of which events to be sent by binding an object containing that list to the transaction using <code>TransactionSynchronizationManager.bindResource</code>.</p> <p>I would advise against trying to use your own <code>ThreadLocal</code> for this, because that would go wrong in some cases; for example if inside your transaction you would start a new transaction (<code>RequiresNew</code>).</p> <p>Differences with your current setup:</p> <ul> <li>if an exception is thrown in the handling of the events in this case, your service will throw the exception, but the changes will already have been committed in the database. </li> <li>if one of your listeners also writes into the database, it will have to do so in a new transaction.</li> </ul> <p>Alternatively, you can use <code>beforeCommit</code> instead of <code>afterCommit</code>, but then your events will be handled (mails sent,...) even if the actual commit to the database later fails.</p> <p>This is less robust (<em>less transactional</em>), than using JMS, but lighter and easier to set up, and usually <em>good enough</em>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload