Skip to content

Commit 6d94c92

Browse files
committed
DefaultMessageListenerContainer's skips no-message-received commit on Tibco (avoiding a deadlock; SPR-7558)
1 parent 3f04625 commit 6d94c92

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

org.springframework.jms/src/main/java/org/springframework/jms/listener/AbstractPollingMessageListenerContainer.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ public abstract class AbstractPollingMessageListenerContainer extends AbstractMe
9797

9898
private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT;
9999

100+
private volatile Boolean commitAfterNoMessageReceived;
101+
100102

101103
public void setSessionTransacted(boolean sessionTransacted) {
102104
super.setSessionTransacted(sessionTransacted);
@@ -351,7 +353,10 @@ protected boolean doReceiveAndExecute(
351353
}
352354
noMessageReceived(invoker, sessionToUse);
353355
// Nevertheless call commit, in order to reset the transaction timeout (if any).
354-
commitIfNecessary(sessionToUse, message);
356+
// However, don't do this on Tibco since this may lead to a deadlock there.
357+
if (shouldCommitAfterNoMessageReceived(sessionToUse)) {
358+
commitIfNecessary(sessionToUse, message);
359+
}
355360
// Indicate that no message has been received.
356361
return false;
357362
}
@@ -379,6 +384,21 @@ protected boolean isSessionLocallyTransacted(Session session) {
379384
!resourceHolder.containsSession(session));
380385
}
381386

387+
/**
388+
* Determine whether to trigger a commit after no message has been received.
389+
* This is a good idea on any JMS provider other than Tibco, which is what
390+
* this default implementation checks for.
391+
* @param session the current JMS Session which received no message
392+
* @return whether to call {@link #commitIfNecessary} on the given Session
393+
*/
394+
protected boolean shouldCommitAfterNoMessageReceived(Session session) {
395+
if (this.commitAfterNoMessageReceived == null) {
396+
Session target = ConnectionFactoryUtils.getTargetSession(session);
397+
this.commitAfterNoMessageReceived = !target.getClass().getName().startsWith("com.tibco.tibjms.");
398+
}
399+
return this.commitAfterNoMessageReceived;
400+
}
401+
382402
/**
383403
* Perform a rollback, handling rollback exceptions properly.
384404
* @param status object representing the transaction

0 commit comments

Comments
 (0)