You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2018/11/13 18:53:03 UTC
commons-dbcp git commit: [DBCP-527 ]Add getters to some classes.
Repository: commons-dbcp
Updated Branches:
refs/heads/master afc2d3ddd -> 34cd3da6f
[DBCP-527 ]Add getters to some classes.
Project: http://git-wip-us.apache.org/repos/asf/commons-dbcp/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-dbcp/commit/34cd3da6
Tree: http://git-wip-us.apache.org/repos/asf/commons-dbcp/tree/34cd3da6
Diff: http://git-wip-us.apache.org/repos/asf/commons-dbcp/diff/34cd3da6
Branch: refs/heads/master
Commit: 34cd3da6f240bdd9a0e0844923715ad1fb7a6cc4
Parents: afc2d3d
Author: Gary Gregory <ga...@gmail.com>
Authored: Tue Nov 13 11:53:00 2018 -0700
Committer: Gary Gregory <ga...@gmail.com>
Committed: Tue Nov 13 11:53:00 2018 -0700
----------------------------------------------------------------------
src/changes/changes.xml | 3 +
.../dbcp2/DataSourceConnectionFactory.java | 21 ++
.../commons/dbcp2/DriverConnectionFactory.java | 21 ++
.../dbcp2/DriverManagerConnectionFactory.java | 37 ++-
.../commons/dbcp2/PoolableConnection.java | 21 ++
.../dbcp2/PoolableConnectionFactory.java | 82 ++++-
.../managed/DataSourceXAConnectionFactory.java | 130 ++++----
.../dbcp2/managed/LocalXAConnectionFactory.java | 323 ++++++++++---------
.../dbcp2/managed/ManagedConnection.java | 288 +++++++++--------
.../dbcp2/managed/ManagedDataSource.java | 31 +-
.../managed/PoolableManagedConnection.java | 7 +
.../PoolableManagedConnectionFactory.java | 7 +
12 files changed, 604 insertions(+), 367 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index c0b2c3c..98f341c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -82,6 +82,9 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="update" issue="DBCP-520" due-to="Zheng Feng">
BasicManagedDataSource needs to pass the TSR with creating DataSourceXAConnectionFactory.
</action>
+ <action dev="ggregory" type="add" issue="DBCP-527" due-to="Gary Gregory">
+ Add getters to some classes.
+ </action>
</release>
<release version="2.5.0" date="2018-07-15" description="This is a minor release, including bug fixes and enhancements.">
<action dev="ggregory" type="update" issue="DBCP-505" due-to="Gary Gregory">
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/DataSourceConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DataSourceConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/DataSourceConnectionFactory.java
index 61ea019..050c3bb 100644
--- a/src/main/java/org/apache/commons/dbcp2/DataSourceConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/DataSourceConnectionFactory.java
@@ -84,4 +84,25 @@ public class DataSourceConnectionFactory implements ConnectionFactory {
}
return dataSource.getConnection(userName, Utils.toString(userPassword));
}
+
+ /**
+ * @since 2.6.0
+ */
+ public DataSource getDataSource() {
+ return dataSource;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public String getUserName() {
+ return userName;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public char[] getUserPassword() {
+ return userPassword;
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
index 42de432..ba88b76 100644
--- a/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/DriverConnectionFactory.java
@@ -53,6 +53,27 @@ public class DriverConnectionFactory implements ConnectionFactory {
return driver.connect(connectionString, properties);
}
+ /**
+ * @since 2.6.0
+ */
+ public String getConnectionString() {
+ return connectionString;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Driver getDriver() {
+ return driver;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
@Override
public String toString() {
return this.getClass().getName() + " [" + String.valueOf(driver) + ";" + String.valueOf(connectionString) + ";"
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/DriverManagerConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/DriverManagerConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/DriverManagerConnectionFactory.java
index c320b2a..24c506c 100644
--- a/src/main/java/org/apache/commons/dbcp2/DriverManagerConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/DriverManagerConnectionFactory.java
@@ -38,6 +38,14 @@ public class DriverManagerConnectionFactory implements ConnectionFactory {
DriverManager.getDrivers();
}
+ private final String connectionUri;
+
+ private final String userName;
+
+ private final String userPassword;
+
+ private final Properties properties;
+
/**
* Constructor for DriverManagerConnectionFactory.
*
@@ -48,6 +56,8 @@ public class DriverManagerConnectionFactory implements ConnectionFactory {
public DriverManagerConnectionFactory(final String connectionUri) {
this.connectionUri = connectionUri;
this.properties = new Properties();
+ this.userName = null;
+ this.userPassword = null;
}
/**
@@ -62,6 +72,8 @@ public class DriverManagerConnectionFactory implements ConnectionFactory {
public DriverManagerConnectionFactory(final String connectionUri, final Properties properties) {
this.connectionUri = connectionUri;
this.properties = properties;
+ this.userName = null;
+ this.userPassword = null;
}
/**
@@ -79,6 +91,7 @@ public class DriverManagerConnectionFactory implements ConnectionFactory {
this.connectionUri = connectionUri;
this.userName = userName;
this.userPassword = userPassword;
+ this.properties = null;
}
@Override
@@ -92,8 +105,24 @@ public class DriverManagerConnectionFactory implements ConnectionFactory {
return DriverManager.getConnection(connectionUri, properties);
}
- private final String connectionUri;
- private String userName;
- private String userPassword;
- private Properties properties;
+ /**
+ * @since 2.6.0
+ */
+ public String getConnectionUri() {
+ return connectionUri;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public String getUserName() {
+ return userName;
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java b/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
index 046e3ab..e9924ae 100644
--- a/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
+++ b/src/main/java/org/apache/commons/dbcp2/PoolableConnection.java
@@ -329,4 +329,25 @@ public class PoolableConnection extends DelegatingConnection<Connection> impleme
fatalSqlExceptionThrown |= isDisconnectionSqlException(e);
super.handleException(e);
}
+
+ /**
+ * @since 2.6.0
+ */
+ public ObjectNameWrapper getJmxObjectName() {
+ return jmxObjectName;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Collection<String> getDisconnectionSqlCodes() {
+ return disconnectionSqlCodes;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public boolean isFastFailValidation() {
+ return fastFailValidation;
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
index 8b4bfaa..2aff632 100644
--- a/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/PoolableConnectionFactory.java
@@ -468,7 +468,10 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
return maxOpenPreparedStatements;
}
- protected boolean getCacheState() {
+ /**
+ * @since Made public in 2.6.0.
+ */
+ public boolean getCacheState() {
return cacheState;
}
@@ -506,4 +509,81 @@ public class PoolableConnectionFactory implements PooledObjectFactory<PoolableCo
* Internal constant to indicate the level is not set.
*/
static final int UNKNOWN_TRANSACTIONISOLATION = -1;
+
+ /**
+ * @since 2.6.0
+ */
+ public ObjectName getDataSourceJmxObjectName() {
+ return dataSourceJmxObjectName;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public String getValidationQuery() {
+ return validationQuery;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public int getValidationQueryTimeoutSeconds() {
+ return validationQueryTimeoutSeconds;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Collection<String> getConnectionInitSqls() {
+ return connectionInitSqls;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Boolean getDefaultReadOnly() {
+ return defaultReadOnly;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Boolean getDefaultAutoCommit() {
+ return defaultAutoCommit;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public int getDefaultTransactionIsolation() {
+ return defaultTransactionIsolation;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public String getDefaultCatalog() {
+ return defaultCatalog;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public String getDefaultSchema() {
+ return defaultSchema;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public long getMaxConnLifetimeMillis() {
+ return maxConnLifetimeMillis;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public Integer getDefaultQueryTimeoutSeconds() {
+ return defaultQueryTimeoutSeconds;
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/DataSourceXAConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/DataSourceXAConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/managed/DataSourceXAConnectionFactory.java
index a23fe0e..b89ca63 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/DataSourceXAConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/DataSourceXAConnectionFactory.java
@@ -51,21 +51,6 @@ public class DataSourceXAConnectionFactory implements XAConnectionFactory {
* the transaction manager in which connections will be enlisted
* @param xaDataSource
* the data source from which connections will be retrieved
- * @param transactionSynchronizationRegistry
- * register with this TransactionSynchronizationRegistry
- */
- public DataSourceXAConnectionFactory(final TransactionManager transactionManager, final XADataSource xaDataSource, final TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
- this(transactionManager, xaDataSource, null, (char[]) null, transactionSynchronizationRegistry);
- }
-
- /**
- * Creates an DataSourceXAConnectionFactory which uses the specified XADataSource to create database connections.
- * The connections are enlisted into transactions using the specified transaction manager.
- *
- * @param transactionManager
- * the transaction manager in which connections will be enlisted
- * @param xaDataSource
- * the data source from which connections will be retrieved
* @since 2.6.0
*/
public DataSourceXAConnectionFactory(final TransactionManager transactionManager, final XADataSource xaDataSource) {
@@ -138,48 +123,18 @@ public class DataSourceXAConnectionFactory implements XAConnectionFactory {
}
/**
- * Gets the user name used to authenticate new connections.
- *
- * @return the user name or null if unauthenticated connections are used
- */
- public String getUsername() {
- return userName;
- }
-
- /**
- * Sets the user name used to authenticate new connections.
- *
- * @param userName
- * the user name used for authenticating the connection or null for unauthenticated
- */
- public void setUsername(final String userName) {
- this.userName = userName;
- }
-
- /**
- * Sets the password used to authenticate new connections.
- *
- * @param userPassword
- * the password used for authenticating the connection or null for unauthenticated.
- * @since 2.4.0
- */
- public void setPassword(final char[] userPassword) {
- this.userPassword = userPassword;
- }
-
- /**
- * Sets the password used to authenticate new connections.
+ * Creates an DataSourceXAConnectionFactory which uses the specified XADataSource to create database connections.
+ * The connections are enlisted into transactions using the specified transaction manager.
*
- * @param userPassword
- * the password used for authenticating the connection or null for unauthenticated
+ * @param transactionManager
+ * the transaction manager in which connections will be enlisted
+ * @param xaDataSource
+ * the data source from which connections will be retrieved
+ * @param transactionSynchronizationRegistry
+ * register with this TransactionSynchronizationRegistry
*/
- public void setPassword(final String userPassword) {
- this.userPassword = Utils.toCharArray(userPassword);
- }
-
- @Override
- public TransactionRegistry getTransactionRegistry() {
- return transactionRegistry;
+ public DataSourceXAConnectionFactory(final TransactionManager transactionManager, final XADataSource xaDataSource, final TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
+ this(transactionManager, xaDataSource, null, (char[]) null, transactionSynchronizationRegistry);
}
@Override
@@ -224,4 +179,69 @@ public class DataSourceXAConnectionFactory implements XAConnectionFactory {
return connection;
}
+
+ @Override
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
+ }
+
+ /**
+ * Gets the user name used to authenticate new connections.
+ *
+ * @return the user name or null if unauthenticated connections are used
+ * @deprecated Use {@link #getUserName()}.
+ */
+ @Deprecated
+ public String getUsername() {
+ return userName;
+ }
+
+ /**
+ * Gets the user name used to authenticate new connections.
+ *
+ * @return the user name or null if unauthenticated connections are used
+ * @since 2.6.0
+ */
+ public String getUserName() {
+ return userName;
+ }
+
+ public char[] getUserPassword() {
+ return userPassword;
+ }
+
+ public XADataSource getXaDataSource() {
+ return xaDataSource;
+ }
+
+ /**
+ * Sets the password used to authenticate new connections.
+ *
+ * @param userPassword
+ * the password used for authenticating the connection or null for unauthenticated.
+ * @since 2.4.0
+ */
+ public void setPassword(final char[] userPassword) {
+ this.userPassword = userPassword;
+ }
+
+ /**
+ * Sets the password used to authenticate new connections.
+ *
+ * @param userPassword
+ * the password used for authenticating the connection or null for unauthenticated
+ */
+ public void setPassword(final String userPassword) {
+ this.userPassword = Utils.toCharArray(userPassword);
+ }
+
+ /**
+ * Sets the user name used to authenticate new connections.
+ *
+ * @param userName
+ * the user name used for authenticating the connection or null for unauthenticated
+ */
+ public void setUsername(final String userName) {
+ this.userName = userName;
+ }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/LocalXAConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/LocalXAConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/managed/LocalXAConnectionFactory.java
index 1eb3c0e..990aab1 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/LocalXAConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/LocalXAConnectionFactory.java
@@ -35,45 +35,6 @@ import java.util.Objects;
* @since 2.0
*/
public class LocalXAConnectionFactory implements XAConnectionFactory {
- private final TransactionRegistry transactionRegistry;
- private final ConnectionFactory connectionFactory;
-
- /**
- * Creates an LocalXAConnectionFactory which uses the specified connection factory to create database connections.
- * The connections are enlisted into transactions using the specified transaction manager.
- *
- * @param transactionManager
- * the transaction manager in which connections will be enlisted
- * @param connectionFactory
- * the connection factory from which connections will be retrieved
- */
- public LocalXAConnectionFactory(final TransactionManager transactionManager,
- final ConnectionFactory connectionFactory) {
- Objects.requireNonNull(transactionManager, "transactionManager is null");
- Objects.requireNonNull(connectionFactory, "connectionFactory is null");
- this.transactionRegistry = new TransactionRegistry(transactionManager);
- this.connectionFactory = connectionFactory;
- }
-
- @Override
- public TransactionRegistry getTransactionRegistry() {
- return transactionRegistry;
- }
-
- @Override
- public Connection createConnection() throws SQLException {
- // create a new connection
- final Connection connection = connectionFactory.createConnection();
-
- // create a XAResource to manage the connection during XA transactions
- final XAResource xaResource = new LocalXAResource(connection);
-
- // register the xa resource for the connection
- transactionRegistry.registerConnection(connection, xaResource);
-
- return connection;
- }
-
/**
* LocalXAResource is a fake XAResource for non-XA connections. When a transaction is started the connection
* auto-commit is turned off. When the connection is committed or rolled back, the commit or rollback method is
@@ -97,61 +58,44 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
/**
- * Gets the current xid of the transaction branch associated with this XAResource.
- *
- * @return the current xid of the transaction branch associated with this XAResource.
- */
- public synchronized Xid getXid() {
- return currentXid;
- }
-
- /**
- * Signals that a the connection has been enrolled in a transaction. This method saves off the current auto
- * commit flag, and then disables auto commit. The original auto commit setting is restored when the transaction
- * completes.
+ * Commits the transaction and restores the original auto commit setting.
*
* @param xid
* the id of the transaction branch for this connection
* @param flag
- * either XAResource.TMNOFLAGS or XAResource.TMRESUME
+ * ignored
* @throws XAException
- * if the connection is already enlisted in another transaction, or if auto-commit could not be
- * disabled
+ * if connection.commit() throws a SQLException
*/
@Override
- public synchronized void start(final Xid xid, final int flag) throws XAException {
- if (flag == XAResource.TMNOFLAGS) {
- // first time in this transaction
+ public synchronized void commit(final Xid xid, final boolean flag) throws XAException {
+ Objects.requireNonNull(xid, "xid is null");
+ if (this.currentXid == null) {
+ throw new XAException("There is no current transaction");
+ }
+ if (!this.currentXid.equals(xid)) {
+ throw new XAException("Invalid Xid: expected " + this.currentXid + ", but was " + xid);
+ }
- // make sure we aren't already in another tx
- if (this.currentXid != null) {
- throw new XAException("Already enlisted in another transaction with xid " + xid);
+ try {
+ // make sure the connection isn't already closed
+ if (connection.isClosed()) {
+ throw new XAException("Connection is closed");
}
- // save off the current auto commit flag so it can be restored after the transaction completes
- try {
- originalAutoCommit = connection.getAutoCommit();
- } catch (final SQLException ignored) {
- // no big deal, just assume it was off
- originalAutoCommit = true;
+ // A read only connection should not be committed
+ if (!connection.isReadOnly()) {
+ connection.commit();
}
-
- // update the auto commit flag
+ } catch (final SQLException e) {
+ throw (XAException) new XAException().initCause(e);
+ } finally {
try {
- connection.setAutoCommit(false);
+ connection.setAutoCommit(originalAutoCommit);
} catch (final SQLException e) {
- throw (XAException) new XAException("Count not turn off auto commit for a XA transaction")
- .initCause(e);
- }
-
- this.currentXid = xid;
- } else if (flag == XAResource.TMRESUME) {
- if (!xid.equals(this.currentXid)) {
- throw new XAException("Attempting to resume in different transaction: expected " + this.currentXid
- + ", but was " + xid);
+ // ignore
}
- } else {
- throw new XAException("Unknown start flag " + flag);
+ this.currentXid = null;
}
}
@@ -178,6 +122,50 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
/**
+ * Clears the currently associated transaction if it is the specified xid.
+ *
+ * @param xid
+ * the id of the transaction to forget
+ */
+ @Override
+ public synchronized void forget(final Xid xid) {
+ if (xid != null && xid.equals(currentXid)) {
+ currentXid = null;
+ }
+ }
+
+ /**
+ * Always returns 0 since we have no way to set a transaction timeout on a JDBC connection.
+ *
+ * @return always 0
+ */
+ @Override
+ public int getTransactionTimeout() {
+ return 0;
+ }
+
+ /**
+ * Gets the current xid of the transaction branch associated with this XAResource.
+ *
+ * @return the current xid of the transaction branch associated with this XAResource.
+ */
+ public synchronized Xid getXid() {
+ return currentXid;
+ }
+
+ /**
+ * Returns true if the specified XAResource == this XAResource.
+ *
+ * @param xaResource
+ * the XAResource to test
+ * @return true if the specified XAResource == this XAResource; false otherwise
+ */
+ @Override
+ public boolean isSameRM(final XAResource xaResource) {
+ return this == xaResource;
+ }
+
+ /**
* This method does nothing since the LocalXAConnection does not support two-phase-commit. This method will
* return XAResource.XA_RDONLY if the connection isReadOnly(). This assumes that the physical connection is
* wrapped with a proxy that prevents an application from changing the read-only flag while enrolled in a
@@ -209,45 +197,16 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
/**
- * Commits the transaction and restores the original auto commit setting.
+ * Always returns a zero length Xid array. The LocalXAConnectionFactory can not support recovery, so no xids
+ * will ever be found.
*
- * @param xid
- * the id of the transaction branch for this connection
* @param flag
- * ignored
- * @throws XAException
- * if connection.commit() throws a SQLException
+ * ignored since recovery is not supported
+ * @return always a zero length Xid array.
*/
@Override
- public synchronized void commit(final Xid xid, final boolean flag) throws XAException {
- Objects.requireNonNull(xid, "xid is null");
- if (this.currentXid == null) {
- throw new XAException("There is no current transaction");
- }
- if (!this.currentXid.equals(xid)) {
- throw new XAException("Invalid Xid: expected " + this.currentXid + ", but was " + xid);
- }
-
- try {
- // make sure the connection isn't already closed
- if (connection.isClosed()) {
- throw new XAException("Connection is closed");
- }
-
- // A read only connection should not be committed
- if (!connection.isReadOnly()) {
- connection.commit();
- }
- } catch (final SQLException e) {
- throw (XAException) new XAException().initCause(e);
- } finally {
- try {
- connection.setAutoCommit(originalAutoCommit);
- } catch (final SQLException e) {
- // ignore
- }
- this.currentXid = null;
- }
+ public Xid[] recover(final int flag) {
+ return new Xid[0];
}
/**
@@ -280,64 +239,112 @@ public class LocalXAConnectionFactory implements XAConnectionFactory {
}
/**
- * Returns true if the specified XAResource == this XAResource.
+ * Always returns false since we have no way to set a transaction timeout on a JDBC connection.
*
- * @param xaResource
- * the XAResource to test
- * @return true if the specified XAResource == this XAResource; false otherwise
+ * @param transactionTimeout
+ * ignored since we have no way to set a transaction timeout on a JDBC connection
+ * @return always false
*/
@Override
- public boolean isSameRM(final XAResource xaResource) {
- return this == xaResource;
+ public boolean setTransactionTimeout(final int transactionTimeout) {
+ return false;
}
/**
- * Clears the currently associated transaction if it is the specified xid.
+ * Signals that a the connection has been enrolled in a transaction. This method saves off the current auto
+ * commit flag, and then disables auto commit. The original auto commit setting is restored when the transaction
+ * completes.
*
* @param xid
- * the id of the transaction to forget
+ * the id of the transaction branch for this connection
+ * @param flag
+ * either XAResource.TMNOFLAGS or XAResource.TMRESUME
+ * @throws XAException
+ * if the connection is already enlisted in another transaction, or if auto-commit could not be
+ * disabled
*/
@Override
- public synchronized void forget(final Xid xid) {
- if (xid != null && xid.equals(currentXid)) {
- currentXid = null;
+ public synchronized void start(final Xid xid, final int flag) throws XAException {
+ if (flag == XAResource.TMNOFLAGS) {
+ // first time in this transaction
+
+ // make sure we aren't already in another tx
+ if (this.currentXid != null) {
+ throw new XAException("Already enlisted in another transaction with xid " + xid);
+ }
+
+ // save off the current auto commit flag so it can be restored after the transaction completes
+ try {
+ originalAutoCommit = connection.getAutoCommit();
+ } catch (final SQLException ignored) {
+ // no big deal, just assume it was off
+ originalAutoCommit = true;
+ }
+
+ // update the auto commit flag
+ try {
+ connection.setAutoCommit(false);
+ } catch (final SQLException e) {
+ throw (XAException) new XAException("Count not turn off auto commit for a XA transaction")
+ .initCause(e);
+ }
+
+ this.currentXid = xid;
+ } else if (flag == XAResource.TMRESUME) {
+ if (!xid.equals(this.currentXid)) {
+ throw new XAException("Attempting to resume in different transaction: expected " + this.currentXid
+ + ", but was " + xid);
+ }
+ } else {
+ throw new XAException("Unknown start flag " + flag);
}
}
+ }
+ private final TransactionRegistry transactionRegistry;
- /**
- * Always returns a zero length Xid array. The LocalXAConnectionFactory can not support recovery, so no xids
- * will ever be found.
- *
- * @param flag
- * ignored since recovery is not supported
- * @return always a zero length Xid array.
- */
- @Override
- public Xid[] recover(final int flag) {
- return new Xid[0];
- }
+ private final ConnectionFactory connectionFactory;
- /**
- * Always returns 0 since we have no way to set a transaction timeout on a JDBC connection.
- *
- * @return always 0
- */
- @Override
- public int getTransactionTimeout() {
- return 0;
- }
+ /**
+ * Creates an LocalXAConnectionFactory which uses the specified connection factory to create database connections.
+ * The connections are enlisted into transactions using the specified transaction manager.
+ *
+ * @param transactionManager
+ * the transaction manager in which connections will be enlisted
+ * @param connectionFactory
+ * the connection factory from which connections will be retrieved
+ */
+ public LocalXAConnectionFactory(final TransactionManager transactionManager,
+ final ConnectionFactory connectionFactory) {
+ Objects.requireNonNull(transactionManager, "transactionManager is null");
+ Objects.requireNonNull(connectionFactory, "connectionFactory is null");
+ this.transactionRegistry = new TransactionRegistry(transactionManager);
+ this.connectionFactory = connectionFactory;
+ }
- /**
- * Always returns false since we have no way to set a transaction timeout on a JDBC connection.
- *
- * @param transactionTimeout
- * ignored since we have no way to set a transaction timeout on a JDBC connection
- * @return always false
- */
- @Override
- public boolean setTransactionTimeout(final int transactionTimeout) {
- return false;
- }
+ @Override
+ public Connection createConnection() throws SQLException {
+ // create a new connection
+ final Connection connection = connectionFactory.createConnection();
+
+ // create a XAResource to manage the connection during XA transactions
+ final XAResource xaResource = new LocalXAResource(connection);
+
+ // register the xa resource for the connection
+ transactionRegistry.registerConnection(connection, xaResource);
+
+ return connection;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public ConnectionFactory getConnectionFactory() {
+ return connectionFactory;
+ }
+
+ @Override
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
}
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/ManagedConnection.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/ManagedConnection.java b/src/main/java/org/apache/commons/dbcp2/managed/ManagedConnection.java
index 111fc58..7c074e6 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/ManagedConnection.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/ManagedConnection.java
@@ -46,11 +46,25 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class ManagedConnection<C extends Connection> extends DelegatingConnection<C> {
+ /**
+ * Delegates to {@link ManagedConnection#transactionComplete()} for transaction completion events.
+ *
+ * @since 2.0
+ */
+ protected class CompletionListener implements TransactionContextListener {
+ @Override
+ public void afterCompletion(final TransactionContext completedContext, final boolean committed) {
+ if (completedContext == transactionContext) {
+ transactionComplete();
+ }
+ }
+ }
private final ObjectPool<C> pool;
private final TransactionRegistry transactionRegistry;
private final boolean accessToUnderlyingConnectionAllowed;
private TransactionContext transactionContext;
private boolean isSharedConnection;
+
private final Lock lock;
/**
@@ -81,6 +95,143 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
updateTransactionStatus();
}
+ @Override
+ public void close() throws SQLException {
+ if (!isClosedInternal()) {
+ // Don't actually close the connection if in a transaction. The
+ // connection will be closed by the transactionComplete method.
+ //
+ // DBCP-484 we need to make sure setClosedInternal(true) being
+ // invoked if transactionContext is not null as this value will
+ // be modified by the transactionComplete method which could run
+ // in the different thread with the transaction calling back.
+ lock.lock();
+ try {
+ if (transactionContext == null || transactionContext.isTransactionComplete()) {
+ super.close();
+ }
+ } finally {
+ try {
+ setClosedInternal(true);
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void commit() throws SQLException {
+ if (transactionContext != null) {
+ throw new SQLException("Commit can not be set while enrolled in a transaction");
+ }
+ super.commit();
+ }
+
+ @Override
+ public C getDelegate() {
+ if (isAccessToUnderlyingConnectionAllowed()) {
+ return getDelegateInternal();
+ }
+ return null;
+ }
+
+ //
+ // The following methods can't be used while enlisted in a transaction
+ //
+
+ @Override
+ public Connection getInnermostDelegate() {
+ if (isAccessToUnderlyingConnectionAllowed()) {
+ return super.getInnermostDelegateInternal();
+ }
+ return null;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public TransactionContext getTransactionContext() {
+ return transactionContext;
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
+ }
+
+ /**
+ * If false, getDelegate() and getInnermostDelegate() will return null.
+ *
+ * @return if false, getDelegate() and getInnermostDelegate() will return null
+ */
+ public boolean isAccessToUnderlyingConnectionAllowed() {
+ return accessToUnderlyingConnectionAllowed;
+ }
+
+ //
+ // Methods for accessing the delegate connection
+ //
+
+ @Override
+ public void rollback() throws SQLException {
+ if (transactionContext != null) {
+ throw new SQLException("Commit can not be set while enrolled in a transaction");
+ }
+ super.rollback();
+ }
+
+ @Override
+ public void setAutoCommit(final boolean autoCommit) throws SQLException {
+ if (transactionContext != null) {
+ throw new SQLException("Auto-commit can not be set while enrolled in a transaction");
+ }
+ super.setAutoCommit(autoCommit);
+ }
+
+ @Override
+ public void setReadOnly(final boolean readOnly) throws SQLException {
+ if (transactionContext != null) {
+ throw new SQLException("Read-only can not be set while enrolled in a transaction");
+ }
+ super.setReadOnly(readOnly);
+ }
+
+ protected void transactionComplete() {
+ lock.lock();
+ try {
+ transactionContext.completeTransaction();
+ } finally {
+ lock.unlock();
+ }
+
+ // If we were using a shared connection, clear the reference now that
+ // the transaction has completed
+ if (isSharedConnection) {
+ setDelegate(null);
+ isSharedConnection = false;
+ }
+
+ // If this connection was closed during the transaction and there is
+ // still a delegate present close it
+ final Connection delegate = getDelegateInternal();
+ if (isClosedInternal() && delegate != null) {
+ try {
+ setDelegate(null);
+
+ if (!delegate.isClosed()) {
+ delegate.close();
+ }
+ } catch (final SQLException ignored) {
+ // Not a whole lot we can do here as connection is closed
+ // and this is a transaction callback so there is no
+ // way to report the error.
+ }
+ }
+ }
+
private void updateTransactionStatus() throws SQLException {
// if there is a is an active transaction context, assure the transaction context hasn't changed
if (transactionContext != null && !transactionContext.isTransactionComplete()) {
@@ -171,141 +322,4 @@ public class ManagedConnection<C extends Connection> extends DelegatingConnectio
// connection
clearCachedState();
}
-
- @Override
- public void close() throws SQLException {
- if (!isClosedInternal()) {
- // Don't actually close the connection if in a transaction. The
- // connection will be closed by the transactionComplete method.
- //
- // DBCP-484 we need to make sure setClosedInternal(true) being
- // invoked if transactionContext is not null as this value will
- // be modified by the transactionComplete method which could run
- // in the different thread with the transaction calling back.
- lock.lock();
- try {
- if (transactionContext == null || transactionContext.isTransactionComplete()) {
- super.close();
- }
- } finally {
- try {
- setClosedInternal(true);
- } finally {
- lock.unlock();
- }
- }
- }
- }
-
- /**
- * Delegates to {@link ManagedConnection#transactionComplete()} for transaction completion events.
- *
- * @since 2.0
- */
- protected class CompletionListener implements TransactionContextListener {
- @Override
- public void afterCompletion(final TransactionContext completedContext, final boolean committed) {
- if (completedContext == transactionContext) {
- transactionComplete();
- }
- }
- }
-
- protected void transactionComplete() {
- lock.lock();
- try {
- transactionContext.completeTransaction();
- } finally {
- lock.unlock();
- }
-
- // If we were using a shared connection, clear the reference now that
- // the transaction has completed
- if (isSharedConnection) {
- setDelegate(null);
- isSharedConnection = false;
- }
-
- // If this connection was closed during the transaction and there is
- // still a delegate present close it
- final Connection delegate = getDelegateInternal();
- if (isClosedInternal() && delegate != null) {
- try {
- setDelegate(null);
-
- if (!delegate.isClosed()) {
- delegate.close();
- }
- } catch (final SQLException ignored) {
- // Not a whole lot we can do here as connection is closed
- // and this is a transaction callback so there is no
- // way to report the error.
- }
- }
- }
-
- //
- // The following methods can't be used while enlisted in a transaction
- //
-
- @Override
- public void setAutoCommit(final boolean autoCommit) throws SQLException {
- if (transactionContext != null) {
- throw new SQLException("Auto-commit can not be set while enrolled in a transaction");
- }
- super.setAutoCommit(autoCommit);
- }
-
- @Override
- public void commit() throws SQLException {
- if (transactionContext != null) {
- throw new SQLException("Commit can not be set while enrolled in a transaction");
- }
- super.commit();
- }
-
- @Override
- public void rollback() throws SQLException {
- if (transactionContext != null) {
- throw new SQLException("Commit can not be set while enrolled in a transaction");
- }
- super.rollback();
- }
-
- @Override
- public void setReadOnly(final boolean readOnly) throws SQLException {
- if (transactionContext != null) {
- throw new SQLException("Read-only can not be set while enrolled in a transaction");
- }
- super.setReadOnly(readOnly);
- }
-
- //
- // Methods for accessing the delegate connection
- //
-
- /**
- * If false, getDelegate() and getInnermostDelegate() will return null.
- *
- * @return if false, getDelegate() and getInnermostDelegate() will return null
- */
- public boolean isAccessToUnderlyingConnectionAllowed() {
- return accessToUnderlyingConnectionAllowed;
- }
-
- @Override
- public C getDelegate() {
- if (isAccessToUnderlyingConnectionAllowed()) {
- return getDelegateInternal();
- }
- return null;
- }
-
- @Override
- public Connection getInnermostDelegate() {
- if (isAccessToUnderlyingConnectionAllowed()) {
- return super.getInnermostDelegateInternal();
- }
- return null;
- }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java b/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
index edd9ae7..e19464d 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/ManagedDataSource.java
@@ -52,6 +52,25 @@ public class ManagedDataSource<C extends Connection> extends PoolingDataSource<C
this.transactionRegistry = transactionRegistry;
}
+ @Override
+ public Connection getConnection() throws SQLException {
+ if (getPool() == null) {
+ throw new IllegalStateException("Pool has not been set");
+ }
+ if (transactionRegistry == null) {
+ throw new IllegalStateException("TransactionRegistry has not been set");
+ }
+
+ return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
+ }
+
+ /**
+ * @since 2.6.0
+ */
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
+ }
+
/**
* Sets the transaction registry from the XAConnectionFactory used to create the pool. The transaction registry can
* only be set once using either a connector or this setter method.
@@ -67,16 +86,4 @@ public class ManagedDataSource<C extends Connection> extends PoolingDataSource<C
this.transactionRegistry = transactionRegistry;
}
-
- @Override
- public Connection getConnection() throws SQLException {
- if (getPool() == null) {
- throw new IllegalStateException("Pool has not been set");
- }
- if (transactionRegistry == null) {
- throw new IllegalStateException("TransactionRegistry has not been set");
- }
-
- return new ManagedConnection<>(getPool(), transactionRegistry, isAccessToUnderlyingConnectionAllowed());
- }
}
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnection.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnection.java b/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnection.java
index cee7090..5055e61 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnection.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnection.java
@@ -71,6 +71,13 @@ public class PoolableManagedConnection extends PoolableConnection {
}
/**
+ * @since 2.6.0
+ */
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
+ }
+
+ /**
* Actually close the underlying connection.
*/
@Override
http://git-wip-us.apache.org/repos/asf/commons-dbcp/blob/34cd3da6/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnectionFactory.java b/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnectionFactory.java
index 5eb8b94..e62b65d 100644
--- a/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnectionFactory.java
+++ b/src/main/java/org/apache/commons/dbcp2/managed/PoolableManagedConnectionFactory.java
@@ -57,6 +57,13 @@ public class PoolableManagedConnectionFactory extends PoolableConnectionFactory
}
/**
+ * @since 2.6.0
+ */
+ public TransactionRegistry getTransactionRegistry() {
+ return transactionRegistry;
+ }
+
+ /**
* Uses the configured XAConnectionFactory to create a {@link PoolableManagedConnection}. Throws
* <code>IllegalStateException</code> if the connection factory returns null. Also initializes the connection using
* configured initialization SQL (if provided) and sets up a prepared statement pool associated with the