This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 729942f4fdffab284e9ed341e58c3132798a3ff5
Author: opencode <[email protected]>
AuthorDate: Sat Oct 31 23:05:20 2026 +0100

    Disclose what the XA getters actually hand out
    
    Documentation only. XADataSource.getXAConnection() returns a session
    borrowed from the pool, not the driver's physical handle: close() on
    it recycles the session through the pool, which rolls back only local
    work, so a caller that abandons the handle over a prepared XA branch
    parks an in-doubt branch on the next borrower; the spec's prescribed
    getConnection() accessor hands out the raw driver session below every
    facade and interceptor the pool puts on a borrowed handle. The
    credential overload additionally honors the given user only when
    alternateUsernameAllowed is enabled, which it is not by default, so a
    default-configured pool silently runs the borrow under its own
    configured identity. State each deviation where the contract is
    promised.
---
 .../org/apache/tomcat/jdbc/pool/XADataSource.java  | 31 +++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java
index f0a841fd88..7d20bd88e7 100644
--- 
a/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java
+++ 
b/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/XADataSource.java
@@ -25,11 +25,16 @@ import org.apache.tomcat.jdbc.pool.util.MessageFactory;
 /**
  * XA-enabled data source for distributed transaction support.
  * <p>
- * Note that XA support is not provided by this class itself: XA connections 
are obtained from the data source
- * configured through the {@code dataSource} or {@code dataSourceJNDI} 
attribute, which must implement
+ * Note that XA support is not provided by this class itself: XA capability 
comes from the data source configured
+ * through the {@code dataSource} or {@code dataSourceJNDI} attribute, which 
must implement
  * {@link javax.sql.XADataSource} (see {@link 
PoolConfiguration#setDataSource(Object)}). A pool configured with only
  * {@code driverClassName} and {@code url} pools plain JDBC connections; a 
request for an XA connection from such a pool
  * fails with an explicit message naming the missing configuration rather than 
later, inside the transaction manager.
+ * <p>
+ * What the {@code getXAConnection} methods return is nevertheless not that 
configured data source's own handle: it is
+ * a session borrowed from the pool, whose {@code close()} returns the session 
to the pool instead of closing the
+ * physical connection. The deviations from the {@code javax.sql} contract 
that follow from this are stated on those
+ * methods.
  */
 public class XADataSource extends DataSource implements javax.sql.XADataSource 
{
 
@@ -54,6 +59,22 @@ public class XADataSource extends DataSource implements 
javax.sql.XADataSource {
      * <p>
      * This implementation first checks that the pool can provide XA 
connections at all, and fails with an explicit
      * configuration hint when it cannot.
+     * <p>
+     * Deviation from the {@code javax.sql} contract: the returned {@link 
XAConnection} is a handle borrowed from the
+     * pool, not a freshly opened physical connection, so under load this call 
blocks waiting for a free session or
+     * fails with pool exhaustion rather than with a database error. Its 
{@link java.sql.Connection#close() close()}
+     * returns the session to the pool instead of closing the physical 
connection; every XA branch started through the
+     * returned {@link javax.transaction.xa.XAResource} must therefore be 
completed - committed or rolled back - before
+     * {@code close()}, and neither the handle nor its {@code XAResource} may 
be used after it. A handle closed while a
+     * branch stands prepared parks that in-doubt branch, and the database 
locks held for it, on a session the pool
+     * hands to another borrower: the pool's return-time rollback unwinds only 
local work and can never resolve a
+     * prepared branch.
+     * <p>
+     * The connection obtained from the returned handle's
+     * {@link javax.sql.PooledConnection#getConnection()} is the driver's raw 
logical session, not a pool-managed
+     * connection: the pool's interceptors and features do not apply to it, 
and closing it invalidates the session
+     * under the pool's own notion of a live connection. Release the borrowed 
session by closing the handle, not that
+     * connection.
      */
     @Override
     public XAConnection getXAConnection() throws SQLException {
@@ -65,7 +86,11 @@ public class XADataSource extends DataSource implements 
javax.sql.XADataSource {
      * {@inheritDoc}
      * <p>
      * This implementation first checks that the pool can provide XA 
connections at all, and fails with an explicit
-     * configuration hint when it cannot.
+     * configuration hint when it cannot. The returned handle deviates from 
the {@code javax.sql} contract as described
+     * on {@link #getXAConnection()}, and carries one deviation of its own: 
the given credentials are honored only when {@link 
PoolConfiguration#setAlternateUsernameAllowed(boolean)
+     * alternateUsernameAllowed} is enabled, which it is not by default; 
otherwise the borrow proceeds under the pool's
+     * configured user name, exactly as {@link #getConnection(String, String)} 
does, and every XA branch started
+     * through this handle's {@code XAResource} runs under that identity, not 
the one passed in here.
      *
      * @param username The user name
      * @param password The password


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to