From ac81809a5d69ad8ff671e3c1190c0db0ae5e847b 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. --- .../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 c193ea6..e48b245 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 @@ -81,8 +81,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 45a2571..a07fb6e 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 895eb62..a62e0a9 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 @@ -122,8 +122,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 @@ -134,7 +134,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()); } }