This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 11.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit e36a2434340ebf5d6ee9565eed364fad710c4c47 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]
