Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-16491

Order of JMS TransactionSynchronizations should be sortable programmatically

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 5.0.2
    • Fix Version/s: 5.x Backlog
    • Component/s: JMS, Transaction
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      Scenario:
      I have application that consume message from JMS Server A, update row in database and produce messages to multiple JMS queues on different servers. This must be done in transaction and without JTA. Application is written with Spring Boot 2.0.0.M7 (with Spring 5.0.2) with data-jpa and jms starters.

      Problem:
      Application can't use JTA transactions (requirement from client), so I implemented Best effort 1PC pattern. It works nicely but client needs to have specific order of commit/rollback of JMS transactions. In my case he required that outbound messages are committed first and then are committed inbound message.

      When i was reading thru code and documentation i found JmsResourceSynchronization and TransactionSynchronizationManager that are in middle of this functionality.

      If i understand code correctly then while triggering afterCommit, JpaTransactionManager gets list of sorted TransactionSynchronization and sorting is done with AnnotationAwareOrderComparator.sort(). My observation is that order of commit/rollback is based on order in which JMS messages was send (and registered inside TransactionSynchronizationManager).

      Because most methods are static and JmsResourceSynchronization is private, only what i can currently do is ugly and unreliable workaround like this:

      List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
      TransactionSynchronizationManager.clearSynchronization();
      TransactionSynchronizationManager.initSynchronization();
      synchronizations = Lists.reverse(synchronizations);
      synchronizations.forEach(TransactionSynchronizationManager::registerSynchronization);
      

      If this sorting of same implementation of TransactionSynchronization (in my case JmsResourceSynchronization) can be done programmatically from @Configuration classes, that would be great.

        Attachments

          Activity

            People

            Assignee:
            juergen.hoeller Juergen Hoeller
            Reporter:
            ludovit.varga Ludovit Varga
            Last updater:
            Spring Issues Spring Issues
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated:
              Days since last comment:
              3 years, 23 weeks, 5 days ago