Search in sources :

Example 31 with XAConnection

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

the class cdsXid method assertPooledConnIso.

/**
 * Test that isolation is reset on PooledConnection.getConnection()
 * @param pooledConnType   Descripiton of the type of pooled connection
 * @param pc               PooledConnection or XAConnection
 * @throws SQLException
 */
private void assertPooledConnIso(String pooledConnType, PooledConnection pc) throws SQLException {
    Connection conn = pc.getConnection();
    setupDerby1144Table(conn);
    // *** Test isolation level reset on conntype.getConnection()
    conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
    assertIsoLocks(conn, Connection.TRANSACTION_READ_UNCOMMITTED);
    conn.close();
    // Get a new connection with pooledConnType.getConnection()
    // Isolation level should be reset to READ_COMMITTED
    Connection newconn = pc.getConnection();
    assertIsoLocks(newconn, Connection.TRANSACTION_READ_COMMITTED);
}
Also used : Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection)

Example 32 with XAConnection

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

the class cdsXid method testXAHoldability.

/* ------------------ JDBC30 (and up) Fixtures ------------------ */
public void testXAHoldability() throws SQLException, XAException {
    // network protocol error
    if (usingDerbyNetClient())
        return;
    // START XA HOLDABILITY TEST
    XADataSource dscsx = J2EEDataSource.getXADataSource();
    XAConnection xac = dscsx.getXAConnection();
    XAResource xr = xac.getXAResource();
    Xid xid = new cdsXid(25, (byte) 21, (byte) 01);
    Connection conn1 = xac.getConnection();
    // check that autocommit is true; default for a connection
    assertTrue(conn1.getAutoCommit());
    // check that holdability is HOLD_CURSORS_OVER_COMMIT in a default
    // CONNECTION(not in xa transaction yet)
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn1.getHoldability());
    // start a global transaction and default holdability and
    // autocommit will be switched to match Derby XA restrictions
    xr.start(xid, XAResource.TMNOFLAGS);
    // So, now autocommit should be false for connection because it is
    // part of the global transaction
    assertFalse(conn1.getAutoCommit());
    // Connection's holdability is now CLOSE_CURSORS_AT_COMMIT because
    // it is part of the global transaction
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn1.getHoldability());
    xr.end(xid, XAResource.TMSUCCESS);
    conn1.commit();
    conn1.close();
    xid = new cdsXid(27, (byte) 21, (byte) 01);
    xr.start(xid, XAResource.TMNOFLAGS);
    conn1 = xac.getConnection();
    // CONNECTION(in xa transaction) HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn1.getHoldability());
    // Autocommit on Connection inside global transaction should be false
    assertFalse(conn1.getAutoCommit());
    xr.end(xid, XAResource.TMSUCCESS);
    conn1.rollback();
    Connection conn = xac.getConnection();
    conn.setAutoCommit(false);
    conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
    // CONNECTION(non-xa transaction) HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability());
    Statement s = conn.createStatement();
    // STATEMENT HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    s.executeUpdate("insert into hold_30 values " + "(1,'init2'), (2, 'init3'), (3,'init3')");
    s.executeUpdate("insert into hold_30 values " + "(4,'init4'), (5, 'init5'), (6,'init6')");
    s.executeUpdate("insert into hold_30 values " + "(7,'init7'), (8, 'init8'), (9,'init9')");
    // STATEMENT HOLDABILITY :
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    Statement sh = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    PreparedStatement psh = conn.prepareStatement("select id from hold_30 for update", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    CallableStatement csh = conn.prepareCall("select id from hold_30 for update", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    // STATEMENT HOLDABILITY :
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, sh.getResultSetHoldability());
    // PREPARED STATEMENT HOLDABILITY :
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, psh.getResultSetHoldability());
    // CALLABLE STATEMENT HOLDABILITY :
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, csh.getResultSetHoldability());
    ResultSet rsh = sh.executeQuery("select id from hold_30 for update");
    rsh.next();
    // H@1 id
    assertEquals(1, rsh.getInt(1));
    rsh.next();
    // H@2 id
    assertEquals(2, rsh.getInt(1));
    conn.commit();
    rsh.next();
    // H@3 id
    assertEquals(3, rsh.getInt(1));
    conn.commit();
    xid = new cdsXid(23, (byte) 21, (byte) 01);
    xr.start(xid, XAResource.TMNOFLAGS);
    Statement stmtInsideGlobalTransaction = conn.createStatement();
    PreparedStatement prepstmtInsideGlobalTransaction = conn.prepareStatement("select id from hold_30");
    CallableStatement callablestmtInsideGlobalTransaction = conn.prepareCall("select id from hold_30");
    // CONNECTION(xa) HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability());
    // STATEMENT(this one was created with holdability false, outside the
    // global transaction. Check its holdability inside global transaction
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    // than embedded.
    if (usingEmbedded())
        assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, sh.getResultSetHoldability());
    else if (usingDerbyNetClient())
        assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, sh.getResultSetHoldability());
    // STATEMENT(this one was created with default holdability inside this
    // global transaction. Check its holdability:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtInsideGlobalTransaction.getResultSetHoldability());
    // PREPAREDSTATEMENT(this one was created with default holdability
    // inside this global transaction. Check its holdability:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, prepstmtInsideGlobalTransaction.getResultSetHoldability());
    // CALLABLESTATEMENT(this one was created with default holdability
    // inside this global transaction. Check its holdability:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, callablestmtInsideGlobalTransaction.getResultSetHoldability());
    ResultSet rsx = s.executeQuery("select id from hold_30 for update");
    rsx.next();
    // X@1 id
    assertEquals(1, rsx.getInt(1));
    rsx.next();
    // X@2 id
    assertEquals(2, rsx.getInt(1));
    xr.end(xid, XAResource.TMSUCCESS);
    // XAConnection
    try {
        rsx.next();
        fail("rsx's connection not active id ");
    } catch (SQLException sqle) {
        assertSQLState("08003", sqle);
    }
    // the xa start.
    try {
        rsh.next();
        fail("rsh's connection not active id ");
    } catch (SQLException sqle) {
        assertSQLState("XCL16", sqle);
    }
    // resume XA transaction and keep using rs");
    xr.start(xid, XAResource.TMJOIN);
    Statement stmtAfterGlobalTransactionResume = conn.createStatement();
    PreparedStatement prepstmtAfterGlobalTransactionResume = conn.prepareStatement("select id from hold_30");
    CallableStatement callablestmtAfterGlobalTransactionResume = conn.prepareCall("select id from hold_30");
    // Check holdability of various jdbc objects after resuming XA
    // transaction
    // CONNECTION(xa) HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability());
    // STATEMENT(this one was created with holdability false, outside the
    // global transaction. Check its holdability inside global transaction
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    // global transaction. Check its holdability inside global transaction
    if (usingEmbedded())
        assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, sh.getResultSetHoldability());
    else if (usingDerbyNetClient())
        assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, sh.getResultSetHoldability());
    // STATEMENT(this one was created with default holdability inside the
    // global transaction when it was first started. Check its holdability
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtInsideGlobalTransaction.getResultSetHoldability());
    // PREPAREDSTATEMENT(this one was created with default holdability
    // inside the global transaction when it was first started. Check its
    // holdability)
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, prepstmtInsideGlobalTransaction.getResultSetHoldability());
    // CALLABLESTATEMENT(this one was created with default holdability
    // inside the global transaction when it was first started. Check its
    // holdability) HOLDABILITY
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, callablestmtInsideGlobalTransaction.getResultSetHoldability());
    // STATEMENT(this one was created with default holdability after the
    // global transaction was resumed. Check its holdability
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, stmtAfterGlobalTransactionResume.getResultSetHoldability());
    // PREPAREDSTATEMENT(this one was created with default holdability
    // after the global transaction was resumed. Check its holdability
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, prepstmtAfterGlobalTransactionResume.getResultSetHoldability());
    // CALLABLESTATEMENT(this one was created with default holdability
    // after the global transaction was resumed. Check its holdability
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, callablestmtAfterGlobalTransactionResume.getResultSetHoldability());
    // DERBY-1370
    if (usingEmbedded()) {
        // Network XA BUG gives result set closed
        rsx.next();
        // X@3 id
        assertEquals(3, rsx.getInt(1));
    }
    xr.end(xid, XAResource.TMSUCCESS);
    if (xr.prepare(xid) != XAResource.XA_RDONLY)
        xr.commit(xid, false);
    // try again once the xa transaction has been committed.
    try {
        rsx.next();
        fail("rsx's connection not active id (B)");
    } catch (SQLException sqle) {
        assertSQLState("XCL16", sqle);
    }
    try {
        rsh.next();
        fail("rsh's should be closed (B)");
    } catch (SQLException sqle) {
        assertSQLState("XCL16", sqle);
    }
    // Set connection to hold
    conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
    // CONNECTION(held) HOLDABILITY:
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
    xid = new cdsXid(24, (byte) 21, (byte) 01);
    xr.start(xid, XAResource.TMNOFLAGS);
    // CONNECTION(xa) HOLDABILITY:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, conn.getHoldability());
    try {
        conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
        fail("allowed to set hold mode in xa transaction");
    } catch (SQLException sqle) {
        assertSQLState("XJ05C", sqle);
    }
    // JDBC 4.0 (proposed final draft) section 16.1.3.1 allows Statements
    // to be created with a different holdability if the driver cannot
    // support it. In this case the driver does not support holdability in
    // a global transaction, so a valid statement is returned with close
    // cursors on commit.
    Statement shxa = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    // HOLDABLE Statement in global xact "
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    assertErrorCode(10000, conn.getWarnings());
    shxa.close();
    shxa = conn.prepareStatement("select id from hold_30", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    // HOLDABLE PreparedStatement in global xact
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    assertErrorCode(10000, conn.getWarnings());
    shxa.close();
    shxa = conn.prepareCall("CALL SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE()", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
    // HOLDABLE CallableStatement in global xact:
    assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, s.getResultSetHoldability());
    assertErrorCode(10000, conn.getWarnings());
    shxa.close();
    // DERBY-1370
    if (usingEmbedded()) {
        // STATEMENT HOLDABILITY:
        assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, sh.getResultSetHoldability());
        sh.executeQuery("select id from hold_30").close();
        sh.execute("select id from hold_30");
        sh.getResultSet().close();
        // PREPARED STATEMENT HOLDABILITY:
        assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, psh.getResultSetHoldability());
        psh.executeQuery().close();
        psh.execute();
        psh.getResultSet().close();
        // CALLABLE STATEMENT HOLDABILITY:
        assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, csh.getResultSetHoldability());
        csh.executeQuery().close();
        csh.execute();
        csh.getResultSet().close();
    }
    // but an update works
    sh.executeUpdate("insert into hold_30 values(10, 'init10')");
    xr.end(xid, XAResource.TMSUCCESS);
    // CONNECTION(held) HOLDABILITY:
    assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, conn.getHoldability());
    s.close();
    sh.close();
    csh.close();
    psh.close();
    rsx.close();
    stmtInsideGlobalTransaction.close();
    prepstmtInsideGlobalTransaction.close();
    callablestmtInsideGlobalTransaction.close();
    stmtAfterGlobalTransactionResume.close();
    prepstmtAfterGlobalTransactionResume.close();
    callablestmtAfterGlobalTransactionResume.close();
    conn.close();
    xac.close();
    TestConfiguration.getCurrent().shutdownDatabase();
// END XA HOLDABILITY TEST");
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CallableStatement(java.sql.CallableStatement) CallableStatement(java.sql.CallableStatement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) XAConnection(javax.sql.XAConnection)

Example 33 with XAConnection

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

the class DataSourcePropertiesTest method embeddedTestAttributesAsPasswordWithPassword_xa.

/**
 * Tests that the <code>attributesAsPassword</code> property of an
 * <code>XADataSource</code> causes an explicitly specified password to be
 * sent as a property string.
 */
public void embeddedTestAttributesAsPasswordWithPassword_xa() throws Exception {
    XADataSource ds = J2EEDataSource.getXADataSource();
    JDBCDataSource.setBeanProperty(ds, "attributesAsPassword", Boolean.TRUE);
    try {
        XAConnection xa = ds.getXAConnection("username", "mypassword");
        fail("Expected getXAConnection to fail.");
    } catch (SQLException e) {
        // expect error because of malformed url
        assertSQLState("XJ028", e);
    }
}
Also used : XADataSource(javax.sql.XADataSource) SQLException(java.sql.SQLException) XAConnection(javax.sql.XAConnection)

Example 34 with XAConnection

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

the class Derby5165Test method testXAUpdateLockKeptPastDBRestart.

public void testXAUpdateLockKeptPastDBRestart() throws InterruptedException, SQLException, XAException {
    if (usingDerbyNetClient())
        return;
    // step 0 - initialize db and xa constructs
    XADataSource xads = J2EEDataSource.getXADataSource();
    J2EEDataSource.setBeanProperty(xads, "databaseName", "d5165db");
    XAConnection xac = xads.getXAConnection();
    XAResource xar = xac.getXAResource();
    Connection conn = xac.getConnection();
    // step 1 - perform update with XA, using Xid xid1
    Statement s = conn.createStatement();
    String tableName = "d5165t";
    createAndLoadTable(conn, tableName, true);
    conn.commit();
    JDBC.assertSingleValueResultSet(s.executeQuery("select * from " + tableName), "1");
    conn.close();
    s.close();
    Xid xid1 = new MyXid(1, 2, 3);
    xar.start(xid1, XAResource.TMNOFLAGS);
    Connection c1 = xac.getConnection();
    Statement s1 = c1.createStatement();
    s1.execute("update " + tableName + " set x = 2 where x = 1");
    xar.end(xid1, XAResource.TMSUCCESS);
    // step 2-prepare xid1 with XA but do NOT commit
    xar.prepare(xid1);
    // step 3 - 'restart' the database
    try {
        // so first shutdown the database
        DataSource ds = JDBCDataSource.getDataSource("d5165db");
        JDBCDataSource.shutdownDatabase(ds);
    } catch (Exception e) {
    // Ignore shutdown successful exception
    }
    // the next Connection call automatically starts up the database again
    Connection c2 = openConnection("d5165db");
    // step 4 - if the bug occurs, the updates of step 1 will be visible
    // however, the XA transaction was not committed, so this should
    // time out.
    Statement s2 = c2.createStatement();
    try {
        ResultSet rs = s2.executeQuery("select * from " + tableName);
        // System.out.println("Contents of T:");
        while (rs.next()) {
            // System.out.println(rs.getInt(1));
            rs.getInt(1);
        }
        rs.close();
        fail("expected a timeout");
    } catch (SQLException sqle) {
        // for debugging uncomment following lines:
        // System.out.println("expected exception: ");
        // e.printStackTrace();
        assertSQLState("40XL1", sqle);
    }
    s.close();
    c2.close();
    s2.close();
    xac.close();
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) SQLException(java.sql.SQLException) Statement(java.sql.Statement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) ResultSet(java.sql.ResultSet) SQLException(java.sql.SQLException) XAException(javax.transaction.xa.XAException) XAConnection(javax.sql.XAConnection) XADataSource(javax.sql.XADataSource) J2EEDataSource(org.apache.derbyTesting.junit.J2EEDataSource) DataSource(javax.sql.DataSource) JDBCDataSource(org.apache.derbyTesting.junit.JDBCDataSource)

Example 35 with XAConnection

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

the class Derby5165Test method testXAInsertLockKeptPastDBRestart.

public void testXAInsertLockKeptPastDBRestart() throws InterruptedException, SQLException, XAException {
    if (usingDerbyNetClient())
        return;
    // open a connection to force creation of the second database
    Connection ctmp = openConnection("d5165db2");
    ctmp.close();
    // step 0 - initialize db and xa constructs
    XADataSource xads = J2EEDataSource.getXADataSource();
    J2EEDataSource.setBeanProperty(xads, "databaseName", "d5165db2");
    XAConnection xac = xads.getXAConnection();
    XAResource xar = xac.getXAResource();
    Connection conn = xac.getConnection();
    // step 1 - perform insert with XA, using Xid xid1
    Statement s = conn.createStatement();
    String tableName = "d5165t";
    createAndLoadTable(conn, tableName, true);
    conn.commit();
    JDBC.assertSingleValueResultSet(s.executeQuery("select * from " + tableName), "1");
    conn.close();
    s.close();
    Xid xid1 = new MyXid(1, 2, 3);
    xar.start(xid1, XAResource.TMNOFLAGS);
    Connection c1 = xac.getConnection();
    Statement s1 = c1.createStatement();
    s1.execute("insert into " + tableName + " values 2");
    xar.end(xid1, XAResource.TMSUCCESS);
    // step 2-prepare xid1 with XA but do NOT commit
    xar.prepare(xid1);
    // step 3 - 'restart' the database
    try {
        // so first shutdown the database
        DataSource ds = JDBCDataSource.getDataSource("d5165db2");
        JDBCDataSource.shutdownDatabase(ds);
    } catch (Exception e) {
    // Ignore shutdown successful exception
    }
    // the next Connection call automatically starts up the database again
    Connection c2 = openConnection("d5165db2");
    // step 4 - if the bug occurs, the updates of step 1 will be visible
    // however, the XA transaction was not committed, so this should have
    // timed out.
    Statement s2 = c2.createStatement();
    try {
        ResultSet rs = s2.executeQuery("select * from " + tableName);
        while (rs.next()) {
            // System.out.println(rs.getInt(1));
            rs.getInt(1);
        }
        rs.close();
        fail("expected a timeout");
    } catch (SQLException sqle) {
        assertSQLState("40XL1", sqle);
    }
    s.close();
    c2.close();
    s2.close();
    xac.close();
}
Also used : XADataSource(javax.sql.XADataSource) XAResource(javax.transaction.xa.XAResource) Xid(javax.transaction.xa.Xid) SQLException(java.sql.SQLException) Statement(java.sql.Statement) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) ResultSet(java.sql.ResultSet) SQLException(java.sql.SQLException) XAException(javax.transaction.xa.XAException) XAConnection(javax.sql.XAConnection) XADataSource(javax.sql.XADataSource) J2EEDataSource(org.apache.derbyTesting.junit.J2EEDataSource) DataSource(javax.sql.DataSource) JDBCDataSource(org.apache.derbyTesting.junit.JDBCDataSource)

Aggregations

XAConnection (javax.sql.XAConnection)118 Connection (java.sql.Connection)78 XAResource (javax.transaction.xa.XAResource)57 XADataSource (javax.sql.XADataSource)52 Xid (javax.transaction.xa.Xid)44 Statement (java.sql.Statement)34 SQLException (java.sql.SQLException)31 PooledConnection (javax.sql.PooledConnection)24 PreparedStatement (java.sql.PreparedStatement)23 ResultSet (java.sql.ResultSet)22 Test (org.junit.Test)19 CallableStatement (java.sql.CallableStatement)18 XAException (javax.transaction.xa.XAException)16 FirebirdConnection (org.firebirdsql.jdbc.FirebirdConnection)9 Transaction (javax.transaction.Transaction)8 DataSource (javax.sql.DataSource)7 TestFBXAResource (org.firebirdsql.jaybird.xca.TestFBXAResource)7 XidImpl (org.firebirdsql.jaybird.xca.TestXABase.XidImpl)7 JdbcDataSource (org.h2.jdbcx.JdbcDataSource)7 ConnectionPoolDataSource (javax.sql.ConnectionPoolDataSource)4