Skip to content

Commit

Permalink
Merge pull request #1022 from tomjenkinson/dontnullconnection
Browse files Browse the repository at this point in the history
Do not null the actual connection when delaying close. That means whe…
  • Loading branch information
tomjenkinson committed Sep 27, 2016
2 parents 57b34b1 + d2ac4aa commit 2cf35fa
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,19 +295,9 @@ public void rollback() throws SQLException
*/
public void close() throws SQLException
{
boolean delayClose = false;
try
{
/*
* Need to know whether this particular connection has outstanding
* resources waiting for it. If not then we can close, otherwise we
* can't.
*/

if (!_transactionalDriverXAConnectionConnection.inuse())
{
ConnectionManager.remove(this); // finalize?
}

/*
* Delist resource if within a transaction.
*/
Expand All @@ -322,8 +312,6 @@ public void close() throws SQLException
* connection is enlisted with!
*/

boolean delayClose = false;

if (tx != null)
{
if (_transactionalDriverXAConnectionConnection.validTransaction(tx))
Expand Down Expand Up @@ -366,31 +354,15 @@ public void close() throws SQLException
}
}

tx.registerSynchronization(new ConnectionSynchronization(null, _transactionalDriverXAConnectionConnection));
if (delayClose)
{
tx.registerSynchronization(new ConnectionSynchronization(_theConnection, null));

_theConnection = null;
tx.registerSynchronization(new ConnectionSynchronization(this));
}
}
else
throw new SQLException(jdbcLogger.i18NLogger.get_closeerrorinvalidtx(tx.toString()));
} else {
_transactionalDriverXAConnectionConnection.closeCloseCurrentConnection();
}

if (!delayClose) // close now
{
if (!_theConnection.isClosed()) {
_theConnection.close();
}

_theConnection = null;
}

// what about connections without xaCon?
}
}
catch (IllegalStateException ex)
{
// transaction not running, so ignore.
Expand All @@ -404,7 +376,26 @@ public void close() throws SQLException
SQLException sqlException = new SQLException(jdbcLogger.i18NLogger.get_closeerror());
sqlException.initCause(e1);
throw sqlException;
}
} finally {
if (!delayClose) {
closeImpl();
}
}
}

void closeImpl() throws SQLException {
try {
ConnectionManager.remove(this);
if (!_theConnection.isClosed()) {
_theConnection.close();
}
if (_transactionalDriverXAConnectionConnection != null) {
_transactionalDriverXAConnectionConnection.closeCloseCurrentConnection();
}
} finally {
_theConnection = null;
_transactionalDriverXAConnectionConnection = null;
}
}

public boolean isClosed() throws SQLException
Expand All @@ -414,8 +405,6 @@ public boolean isClosed() throws SQLException
* bound it to a different transaction.
*/

checkTransaction();

if (_theConnection == null)
return false; // not opened yet. // TODO why don't we return true here
else
Expand Down Expand Up @@ -860,16 +849,11 @@ final void reset()
{
try
{
if (_theConnection != null)
_theConnection.close();
closeImpl();
}
catch (Exception ex)
{
}
finally
{
_theConnection = null;
}
}

final java.sql.Connection getConnection() throws SQLException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@

package com.arjuna.ats.internal.jdbc;

import java.sql.Connection;
import com.arjuna.ats.jdbc.logging.jdbcLogger;

import javax.transaction.Synchronization;

import com.arjuna.ats.jta.xa.RecoverableXAConnection;

/**
* A synchronization to close the database connection when the transaction
* has committed or rolled back.
Expand All @@ -47,39 +45,29 @@
public class ConnectionSynchronization implements Synchronization
{

public ConnectionSynchronization (Connection conn, TransactionalDriverXAConnection rxac)
public ConnectionSynchronization (ConnectionImple conn)
{
_theConnection = conn;
_recoveryConnection = rxac;
}

public void afterCompletion(int status)
{
try
{
if (_theConnection != null && !_theConnection.isClosed()) {
_theConnection.close();
}
}
catch (Exception ex)
{
}
try
{
if (_recoveryConnection != null) {
_recoveryConnection.closeCloseCurrentConnection();
}
}
catch (Exception ex)
{
}
try
{
if (_theConnection != null) {
_theConnection.closeImpl();
}
}
catch (Exception ex)
{
jdbcLogger.i18NLogger.warn_not_closed(ex);
}
}

public void beforeCompletion()
{
}

private Connection _theConnection = null;
private TransactionalDriverXAConnection _recoveryConnection;
private ConnectionImple _theConnection = null;
}

Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ public Xid createXid(Xid xid) throws SQLException, NotImplementedException {
@Override
public XAConnection getConnection(XAConnection conn) throws SQLException,
NotImplementedException {
throw new NotImplementedException();
throw new NotImplementedException(); // NEVER CALLED
}

@Override
public boolean supportsMultipleConnections() throws SQLException,
NotImplementedException {
return true; // This is the default
return true; // This ensures connection close is delayed
}

@Override
public void setIsolationLevel(Connection conn, int level)
throws SQLException, NotImplementedException {
// The default implementation does not call this
// Non-modifier path does not call this
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as 2016 by the @author tags.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2016,
* @author JBoss Inc.
*/
package com.arjuna.ats.internal.jdbc.drivers.modifiers;

import com.arjuna.ats.jta.exceptions.NotImplementedException;
import com.arjuna.ats.jta.xa.XAModifier;

import javax.sql.XAConnection;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.SQLException;

public class SupportsMultipleConnectionsModifier implements XAModifier, ConnectionModifier {

@Override
public String initialise(String dbName) {
return dbName;
}

@Override
public Xid createXid(Xid xid) throws SQLException, NotImplementedException {
return xid;
}

@Override
public XAConnection getConnection(XAConnection conn) throws SQLException,
NotImplementedException {
throw new NotImplementedException(); // NEVER CALLED
}

@Override
public boolean supportsMultipleConnections() throws SQLException,
NotImplementedException {
return true; // This ensures connection close is delayed
}

@Override
public void setIsolationLevel(Connection conn, int level)
throws SQLException, NotImplementedException {
// Non-modifier path does not call this
}

@Override
public int xaStartParameters(int level) throws SQLException,
NotImplementedException {
return level;
}

@Override
public boolean requiresSameRMOverride() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ public list ()
"Oracle JDBC driver",
"IBM DB2 JDBC Universal Driver Architecture",
"MySQL Connector Java",
"MySQL-AB JDBC Driver",
"H2 JDBC Driver"}) {
ModifierFactory.putModifier(driver, -1, -1,
IsSameRMModifier.class.getName());
}
}

ModifierFactory.putModifier("PostgreSQL Native Driver", -1, -1,
SupportsMultipleConnectionsModifier.class.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ public interface jdbcI18NLogger {
@Message(id = 17037, value = "Could not resolve JNDI XADataSource", format = MESSAGE_FORMAT)
public String get_xa_recjndierror();

@Message(id = 17038, value = "ConnectionSynchronization could not close connection", format = MESSAGE_FORMAT)
@LogMessage(level = WARN)
void warn_not_closed(@Cause() Throwable arg0);

/*
Allocate new messages directly above this notice.
- id: use the next id number in sequence. Don't reuse ids.
Expand Down

0 comments on commit 2cf35fa

Please sign in to comment.