From 1b8a8a5e25a1acaccd1ffc2cbd318564444c355a Mon Sep 17 00:00:00 2001 From: Timothy Bish Date: Fri, 26 Apr 2024 12:45:11 -0400 Subject: [PATCH] Force the session to be invalidated when XA enlist outcome is unknown Under any error or indeterminate outcome on create of an XA session force the session to be closed and invalidated instead of returning it to the pull. (cherry picked from commit ac81809a5d69ad8ff671e3c1190c0db0ae5e847b) --- .../messaginghub/pooled/jms/JmsPoolSession.java | 10 ++++++++-- .../pooled/jms/pool/PooledXAConnection.java | 14 +++++++++++++- .../pooled/jms/JmsPoolXAConnectionTest.java | 8 ++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolSession.java b/pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolSession.java index fb7a189..e2bd82d 100644 --- a/pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolSession.java +++ b/pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolSession.java @@ -80,8 +80,14 @@ public JmsPoolSession(PooledSessionKey key, PooledSessionHolder sessionHolder, K @Override public void close() throws JMSException { - if (!ignoreClose && closed.compareAndSet(false, true)) { - boolean invalidate = cleanupSession(); + if (!ignoreClose) { + internalClose(false); + } + } + + public void internalClose(boolean forceInvalidate) throws JMSException { + if (closed.compareAndSet(false, true)) { + final boolean invalidate = cleanupSession() || forceInvalidate; if (invalidate) { // lets close the session and not put the session back into the pool diff --git a/pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledXAConnection.java b/pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledXAConnection.java index 7c034d3..7e63462 100644 --- a/pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledXAConnection.java +++ b/pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledXAConnection.java @@ -85,7 +85,7 @@ public Session createSession(boolean transacted, int ackMode) throws JMSExceptio throw new JMSException("Enlistment of Pooled Session into transaction failed"); } } catch (Exception ex) { - sync.close(); + sync.fail(); throw ex; } } @@ -116,6 +116,18 @@ private JmsPooledXASessionSynchronization(JmsPoolSession session) { this.session = session; } + public void fail() throws JMSException { + if (closed.compareAndSet(false, true)) { + // Force the session to close and invalidate itself. + try { + session.internalClose(true); + } finally { + session = null; + decrementReferenceCount(); + } + } + } + public void close() throws JMSException { if (closed.compareAndSet(false, true)) { // This will return session to the pool. diff --git a/pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolXAConnectionTest.java b/pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolXAConnectionTest.java index 6c1532a..9e14d5b 100644 --- a/pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolXAConnectionTest.java +++ b/pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolXAConnectionTest.java @@ -113,8 +113,8 @@ public void testCreateXASessionFailsOnAddSynchronization() throws Exception { assertThrows(JMSException.class, () -> connection.createSession()); - // Session not should be ignoring close at this stage - assertEquals(1, connection.getNumtIdleSessions()); + // Session should be invalidated as we don't know the state after failed register + assertEquals(0, connection.getNumtIdleSessions()); } @Test @@ -125,7 +125,7 @@ public void testCreateXASessionFailsOnEnlist() throws Exception { assertThrows(JMSException.class, () -> connection.createSession()); - // Session not should be ignoring close at this stage - assertEquals(1, connection.getNumtIdleSessions()); + // Session should be invalidated as we don't know the state after failed enlist + assertEquals(0, connection.getNumtIdleSessions()); } }