Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topic messages are not sent when using transacted JmsTemplate in 'TransactionSynchronization.afterCommit' phase [SPR-16270] #20817

Open
spring-issuemaster opened this issue Dec 6, 2017 · 1 comment

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Dec 6, 2017

ofer baranes opened SPR-16270 and commented

On the following scenario, an attempt to send message to a TOPIC using JmsTemplate is not effective (the message is never sent and there is no error):

  1. Open Transaction using spring framework
  2. Register TransactionSynchronization to the active Transaction
  3. On the TransactionSynchronization, implement the 'afterCommit' as below:
  • create JmsTemplate and set it to be 'transacted'
  • send a message to a topic
  1. commit the Transaction

The expectation is that the message would be send and the subscriber would handle it.
On real, the message is never handled by the subscriber. The reason is that the message wasn't truly send.

Other observations:
The expectation is fulfilled and the subscriber gets the message if:
a) Using 'afterCompletion' instead of 'afterCommit',
b) Using none transacted JmsTemplate (on the 'afterCommit')

It appears that Spring determines the existence of an ongoing transaction by checking state

_TransactionSynchronizationManager
public static boolean isSynchronizationActive() {
return synchronizations.get() != null;
}
_

Since the 'synchronizations' thread local is not cleared when executing the 'afterCommit' callback, Spring mistakenly assumes that there is ongoing transaction and hence bounds the JMS operation to the ongoing transaction (instead of commiting it immediately) and since there is no ongoing transaction the JMS operation would never be committed.
(When using 'afterCompletion' it works since the 'synchronizations' thread local was cleared)


Affects: 4.3.11

Issue Links:

  • #16214 TransactionSynchronizationManager - throw an Exception or log a warning if a Synchronization wants to add a Synchronization and afterCompletion is already called
@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Jan 11, 2018

Juergen Hoeller commented

While I agree that this behavior is unintuitive, it is actually documented in the TransactionSynchronization javadoc, explicitly stating that this callback allows for late participation in the transaction... not least of it all for post-commit cleanup steps where the original resources need to be active still. Our recommendation certainly is not to use a transactional JMS setup from that callback, or it really needs to be, to do so within a managed PROPAGATION_REQUIRES_NEW transaction.

That said, we should be doing something to make this more obvious: maybe logging a warning for newly created resources at that point, or even outright rejection of new resource creation after the managed transaction commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.