Search in sources :

Example 56 with XAConnection

use of javax.sql.XAConnection in project tomee by apache.

the class ManagedConnection method invoke.

@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
    // first some Object method management
    final String mtdName = method.getName();
    if ("toString".equals(mtdName)) {
        return "ManagedConnection{" + delegate + "}";
    }
    if ("hashCode".equals(mtdName)) {
        return hashCode();
    }
    if ("equals".equals(mtdName)) {
        InvocationHandler handler;
        return args[0] == this || ((handler = unwrapHandler(args[0])) == this) || (delegate != null && delegate.equals(unwrapDelegate(args[0], handler)));
    }
    // allow to get delegate if needed by the underlying program
    if (Wrapper.class == method.getDeclaringClass() && args.length == 1 && Connection.class == args[0]) {
        if ("isWrapperFor".equals(mtdName)) {
            return true;
        }
        if ("unwrap".equals(mtdName)) {
            return delegate;
        }
    }
    // here the real logic starts
    try {
        final Transaction transaction = transactionManager.getTransaction();
        // shouldn't be used without a transaction but if so just delegate to the actual connection
        if (transaction == null) {
            if ("close".equals(mtdName)) {
                if (delegate == null) {
                    // no need to get a connection
                    return close();
                }
                closeConnection(true);
                return null;
            }
            if ("isClosed".equals(mtdName) && closed) {
                return true;
            }
            if (delegate == null) {
                newConnection();
            }
            return invoke(method, delegate, args);
        }
        // if we have a tx check it is the same this connection is linked to
        if (currentTransaction != null && isUnderTransaction(currentTransaction.getStatus())) {
            if (!currentTransaction.equals(transaction)) {
                throw new SQLException("Connection can not be used while enlisted in another transaction");
            }
            return invokeUnderTransaction(method, args);
        }
        // get the already bound connection to the current transaction or enlist this one in the tx
        final int transactionStatus = transaction.getStatus();
        if (isUnderTransaction(transactionStatus)) {
            Connection connection = Connection.class.cast(registry.getResource(key));
            if (connection == null && delegate == null) {
                newConnection();
                currentTransaction = transaction;
                try {
                    if (!transaction.enlistResource(getXAResource())) {
                        closeConnection(true);
                        throw new SQLException("Unable to enlist connection in transaction: enlistResource returns 'false'.");
                    }
                } catch (final RollbackException ignored) {
                // no-op
                } catch (final SystemException e) {
                    throw new SQLException("Unable to enlist connection the transaction", e);
                }
                registry.putResource(key, proxy);
                transaction.registerSynchronization(new ClosingSynchronization());
                if (xaConnection == null) {
                    try {
                        setAutoCommit(false);
                    } catch (final SQLException xae) {
                        // we are alreay in a transaction so this can't be called from a user perspective - some XA DataSource prevents it in their code
                        final String message = "Can't set auto commit to false cause the XA datasource doesn't support it, this is likely an issue";
                        if (LOGGER.isDebugEnabled()) {
                            // we don't want to print the exception by default
                            LOGGER.warning(message, xae);
                        } else {
                            LOGGER.warning(message);
                        }
                    }
                }
            } else if (delegate == null) {
                // this happens if the caller obtains subsequent connections from the *same* datasource
                // are enlisted in the *same* transaction:
                // connection != null (because it comes from the tx registry)
                // delegate == null (because its a new ManagedConnection instance)
                // we attempt to work-around this by looking up the connection in the tx registry in ManaagedDataSource
                // and ManagedXADataSource, but there is an edge case where the connection is fetch from the datasource
                // first, and a BMT tx is started by the user.
                final ManagedConnection managedConnection = ManagedConnection.class.cast(Proxy.getInvocationHandler(connection));
                this.delegate = managedConnection.delegate;
                this.xaConnection = managedConnection.xaConnection;
                this.xaResource = managedConnection.xaResource;
            }
            return invokeUnderTransaction(method, args);
        }
        if ("isClosed".equals(mtdName) && closed) {
            return true;
        }
        if ("close".equals(mtdName)) {
            // let it be handled by the ClosingSynchronisation since we have a tx there
            return close();
        }
        // we shouldn't come here, tempted to just throw an exception
        if (delegate == null) {
            newConnection();
        }
        return invoke(method, delegate, args);
    } catch (final InvocationTargetException ite) {
        throw ite.getTargetException();
    }
}
Also used : Transaction(javax.transaction.Transaction) SystemException(javax.transaction.SystemException) SQLException(java.sql.SQLException) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) RollbackException(javax.transaction.RollbackException) InvocationHandler(java.lang.reflect.InvocationHandler) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 57 with XAConnection

use of javax.sql.XAConnection in project tomcat by apache.

the class DataSourceXAConnectionFactory method createConnection.

@Override
public Connection createConnection() throws SQLException {
    // create a new XAConnection
    final XAConnection xaConnection;
    if (userName == null) {
        xaConnection = xaDataSource.getXAConnection();
    } else {
        xaConnection = xaDataSource.getXAConnection(userName, Utils.toString(userPassword));
    }
    // get the real connection and XAResource from the connection
    final Connection connection = xaConnection.getConnection();
    final XAResource xaResource = xaConnection.getXAResource();
    // register the xa resource for the connection
    transactionRegistry.registerConnection(connection, xaResource);
    // The Connection we're returning is a handle on the XAConnection.
    // When the pool calling us closes the Connection, we need to
    // also close the XAConnection that holds the physical connection.
    xaConnection.addConnectionEventListener(new ConnectionEventListener() {

        @Override
        public void connectionClosed(final ConnectionEvent event) {
            final PooledConnection pc = (PooledConnection) event.getSource();
            pc.removeConnectionEventListener(this);
            try {
                pc.close();
            } catch (final SQLException e) {
                System.err.println("Failed to close XAConnection");
                e.printStackTrace();
            }
        }

        @Override
        public void connectionErrorOccurred(final ConnectionEvent event) {
            connectionClosed(event);
        }
    });
    return connection;
}
Also used : XAResource(javax.transaction.xa.XAResource) PooledConnection(javax.sql.PooledConnection) SQLException(java.sql.SQLException) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) ConnectionEvent(javax.sql.ConnectionEvent) XAConnection(javax.sql.XAConnection) ConnectionEventListener(javax.sql.ConnectionEventListener)

Example 58 with XAConnection

use of javax.sql.XAConnection in project aries by apache.

the class TxDBServlet method cleanTable.

/**
 * Cleans the Table
 *
 * @param xaDataSource
 * @throws SQLException
 */
private void cleanTable(XADataSource xaDataSource) throws SQLException {
    XAConnection xaConnection = xaDataSource.getXAConnection();
    Connection connection = xaConnection.getConnection();
    PreparedStatement statement = connection.prepareStatement(CLEAN_TABLE);
    statement.executeUpdate();
}
Also used : Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PreparedStatement(java.sql.PreparedStatement) XAConnection(javax.sql.XAConnection)

Example 59 with XAConnection

use of javax.sql.XAConnection in project druid by alibaba.

the class H2XATest method test_0.

public void test_0() throws Exception {
    XAConnection conn = dataSource.getXAConnection();
    conn.close();
}
Also used : XAConnection(javax.sql.XAConnection)

Example 60 with XAConnection

use of javax.sql.XAConnection in project Payara by payara.

the class ManagedConnectionImpl method getXAResource.

/**
 * Returns an <code>XAResource</code> instance.
 *
 * @return <code>XAResource</code> instance
 * @throws ResourceException     if the physical connection is not valid or
 *                               there is an error in allocating the
 *                               <code>XAResource</code> instance
 * @throws NotSupportedException if underlying datasource is not an
 *                               <code>XADataSource</code>
 */
@Override
public XAResource getXAResource() throws ResourceException {
    logFine("In getXAResource");
    checkIfValid();
    if (connectionType == ISXACONNECTION) {
        try {
            if (xar == null) {
                /**
                 * Using the wrapper XAResource.
                 */
                xar = new com.sun.gjc.spi.XAResourceImpl(((XAConnection) pc).getXAResource(), this);
            }
            return xar;
        } catch (SQLException sqle) {
            throw new ResourceException(sqle.getMessage(), sqle);
        }
    } else {
        throw new NotSupportedException("Cannot get an XAResource from a non XA connection");
    }
}
Also used : SQLException(java.sql.SQLException) ResourceException(javax.resource.ResourceException) NotSupportedException(javax.resource.NotSupportedException) XAConnection(javax.sql.XAConnection)

Aggregations

XAConnection (javax.sql.XAConnection)115 Connection (java.sql.Connection)78 XAResource (javax.transaction.xa.XAResource)56 XADataSource (javax.sql.XADataSource)52 Xid (javax.transaction.xa.Xid)44 Statement (java.sql.Statement)34 SQLException (java.sql.SQLException)30 PreparedStatement (java.sql.PreparedStatement)23 PooledConnection (javax.sql.PooledConnection)23 ResultSet (java.sql.ResultSet)22 CallableStatement (java.sql.CallableStatement)18 Test (org.junit.Test)18 XAException (javax.transaction.xa.XAException)16 Transaction (javax.transaction.Transaction)8 DataSource (javax.sql.DataSource)7 XidImpl (org.firebirdsql.jca.TestXABase.XidImpl)7 JdbcDataSource (org.h2.jdbcx.JdbcDataSource)7 NotSupportedException (javax.transaction.NotSupportedException)5 ConnectionPoolDataSource (javax.sql.ConnectionPoolDataSource)4 J2EEDataSource (org.apache.derbyTesting.junit.J2EEDataSource)4