com.atomikos.jdbc.nonxa.AtomikosNonXAPooledConnection Maven / Gradle / Ivy
/**
* Copyright (C) 2000-2017 Atomikos
*
* LICENSE CONDITIONS
*
* See http://www.atomikos.com/Main/WhichLicenseApplies for details.
*/
package com.atomikos.jdbc.nonxa;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import com.atomikos.datasource.pool.AbstractXPooledConnection;
import com.atomikos.datasource.pool.ConnectionPoolProperties;
import com.atomikos.datasource.pool.CreateConnectionException;
import com.atomikos.datasource.pool.Reapable;
import com.atomikos.icatch.CompositeTransaction;
import com.atomikos.icatch.CompositeTransactionManager;
import com.atomikos.icatch.config.Configuration;
import com.atomikos.icatch.jta.TransactionManagerImp;
import com.atomikos.jdbc.JdbcConnectionProxyHelper;
import com.atomikos.logging.Logger;
import com.atomikos.logging.LoggerFactory;
import com.atomikos.util.DynamicProxy;
/**
*
*
* An implementation of XPooledConnection for non-xa drivers.
*
*
*/
class AtomikosNonXAPooledConnection extends AbstractXPooledConnection
{
private static final Logger LOGGER = LoggerFactory.createLogger(AtomikosNonXAPooledConnection.class);
private Connection connection;
private boolean erroneous;
private boolean readOnly;
private ConnectionPoolProperties props;
public AtomikosNonXAPooledConnection ( Connection wrapped , ConnectionPoolProperties props , boolean readOnly )
{
super ( props );
this.connection = wrapped;
this.erroneous = false;
this.readOnly = readOnly;
this.props = props;
}
void setErroneous()
{
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": setErroneous" );
this.erroneous = true;
}
public void destroy()
{
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": destroying..." );
try {
if ( connection != null ) connection.close();
} catch ( SQLException e ) {
//ignore, just log
LOGGER.logWarning ( this + ": Error closing JDBC connection: " , e );
}
}
protected Reapable doCreateConnectionProxy() throws CreateConnectionException
{
Reapable ret = null;
if ( canBeRecycledForCallingThread() ) {
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": reusing existing proxy for thread..." );
ret = getCurrentConnectionProxy();
DynamicProxy dproxy = ( DynamicProxy ) ret;
AtomikosThreadLocalConnection previous = (AtomikosThreadLocalConnection) dproxy.getInvocationHandler();
//DON't increment use count: see case 27793
//previous.incUseCount();
} else {
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": creating connection proxy..." );
JdbcConnectionProxyHelper.setIsolationLevel ( connection, getDefaultIsolationLevel() );
ret = ( Reapable ) AtomikosThreadLocalConnection.newInstance ( this , props.getUniqueResourceName() );
}
return ret;
}
Connection getConnection()
{
return connection;
}
protected void testUnderlyingConnection() throws CreateConnectionException {
String testQuery = getTestQuery();
if ( isErroneous() ) throw new CreateConnectionException ( this + ": connection is erroneous" );
if (testQuery != null) {
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": testing connection with query [" + testQuery + "]" );
Statement stmt = null;
try {
stmt = connection.createStatement();
//use execute instead of executeQuery - cf case 58830
stmt.execute(testQuery);
stmt.close();
} catch ( Exception e) {
//catch any Exception - cf case 22198
throw new CreateConnectionException ( "Error executing testQuery" , e );
}
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": connection tested OK" );
}
else {
if ( LOGGER.isTraceEnabled() ) LOGGER.logTrace ( this + ": no test query, skipping test" );
}
}
public boolean isAvailable() {
boolean ret = true;
Reapable handle = getCurrentConnectionProxy();
if ( handle != null ) {
DynamicProxy dproxy = ( DynamicProxy ) handle;
AtomikosThreadLocalConnection previous = (AtomikosThreadLocalConnection) dproxy.getInvocationHandler();
ret = previous.isNoLongerInUse();
}
return ret;
}
public boolean isErroneous() {
return erroneous;
}
//overridden for package-use here
protected void fireOnXPooledConnectionTerminated()
{
super.fireOnXPooledConnectionTerminated();
updateLastTimeReleased();
}
public String toString()
{
return "AtomikosNonXAPooledConnection";
}
public boolean getReadOnly() {
return readOnly;
}
public boolean canBeRecycledForCallingThread()
{
boolean ret = false;
Reapable handle = getCurrentConnectionProxy();
if ( handle != null ) {
CompositeTransactionManager ctm = Configuration.getCompositeTransactionManager ();
CompositeTransaction ct = null;
if ( ctm != null ) ct = ctm.getCompositeTransaction ();
if ( ct != null && ct.getProperty ( TransactionManagerImp.JTA_PROPERTY_NAME ) != null ) {
DynamicProxy dproxy = ( DynamicProxy ) handle;
AtomikosThreadLocalConnection previous = (AtomikosThreadLocalConnection) dproxy.getInvocationHandler();
ret = previous.isInTransaction ( ct );
}
}
return ret;
}
}