private Connection initConnection(String username, String password) throws SQLException { if (closeSuppressedConnection != null) { if (!borrowedConnection) { borrowedConnection = true; return closeSuppressedConnection; } } Connection target; if (username != null) { target = dataSource.getConnection(username, password); } else { target = dataSource.getConnection(); } return getCloseSuppressingConnectionProxy(target); }
@Override public Connection getConnection() throws SQLException { synchronized (this.connectionMonitor) { return initConnection(null, null); } }
/** * @see SmartDataSource */ @Override public boolean shouldClose(Connection connection) { boolean shouldClose = !isCloseSuppressionActive(connection); if (borrowedConnection && closeSuppressedConnection.equals(connection)) { borrowedConnection = false; } return shouldClose; }
@Test(expected = IllegalArgumentException.class) public void delegateIsRequired() throws Exception { ExtendedConnectionDataSourceProxy tested = new ExtendedConnectionDataSourceProxy(null); tested.afterPropertiesSet(); }
@Test public void testOperationWithDirectCloseCall() throws SQLException { Connection con = mock(Connection.class); DataSource ds = mock(DataSource.class); when(ds.getConnection()).thenReturn(con); // con1 con.close(); when(ds.getConnection()).thenReturn(con); // con2 con.close(); final ExtendedConnectionDataSourceProxy csds = new ExtendedConnectionDataSourceProxy(ds); Connection con1 = csds.getConnection(); csds.startCloseSuppression(con1); Connection con1_1 = csds.getConnection(); assertSame("should be same connection", con1_1, con1); con1_1.close(); // no mock call for this - should be suppressed Connection con1_2 = csds.getConnection(); assertSame("should be same connection", con1_2, con1); Connection con2 = csds.getConnection(); assertNotSame("shouldn't be same connection", con2, con1); csds.stopCloseSuppression(con1); assertTrue("should be able to close connection", csds.shouldClose(con1)); con1_1 = null; con1_2 = null; con1.close(); assertTrue("should be able to close connection", csds.shouldClose(con2)); con2.close(); }
final ExtendedConnectionDataSourceProxy csds = new ExtendedConnectionDataSourceProxy(); csds.setDataSource(ds); PlatformTransactionManager tm = new DataSourceTransactionManager(csds); TransactionTemplate tt = new TransactionTemplate(tm); csds.startCloseSuppression(connection); tt.execute(new TransactionCallback<Void>() { @Override csds.stopCloseSuppression(connection); DataSourceUtils.releaseConnection(connection, csds); template.queryForList("select egg from bar");
@Test public void unwrapForSupportedInterface() throws Exception { DataSourceStub ds = new DataSourceStub(); ExtendedConnectionDataSourceProxy tested = new ExtendedConnectionDataSourceProxy(ds); assertTrue(tested.isWrapperFor(Supported.class)); assertEquals(ds, tested.unwrap(Supported.class)); }
/** * Close the cursor and database connection. Make call to cleanupOnClose so sub classes can cleanup * any resources they have allocated. */ @Override protected void doClose() throws Exception { initialized = false; JdbcUtils.closeResultSet(this.rs); rs = null; cleanupOnClose(); if(this.con != null) { this.con.setAutoCommit(this.initialConnectionAutoCommit); } if (useSharedExtendedConnection && dataSource instanceof ExtendedConnectionDataSourceProxy) { ((ExtendedConnectionDataSourceProxy)dataSource).stopCloseSuppression(this.con); if (!TransactionSynchronizationManager.isActualTransactionActive()) { DataSourceUtils.releaseConnection(con, dataSource); } } else { JdbcUtils.closeConnection(this.con); } }
protected void initializeConnection() { Assert.state(getDataSource() != null, "DataSource must not be null."); try { if (useSharedExtendedConnection) { if (!(getDataSource() instanceof ExtendedConnectionDataSourceProxy)) { throw new InvalidDataAccessApiUsageException( "You must use a ExtendedConnectionDataSourceProxy for the dataSource when " + "useSharedExtendedConnection is set to true."); } this.con = DataSourceUtils.getConnection(dataSource); ((ExtendedConnectionDataSourceProxy)dataSource).startCloseSuppression(this.con); } else { this.con = dataSource.getConnection(); } this.initialConnectionAutoCommit = this.con.getAutoCommit(); if (this.connectionAutoCommit != null && this.con.getAutoCommit() != this.connectionAutoCommit) { this.con.setAutoCommit(this.connectionAutoCommit); } } catch (SQLException se) { close(); throw getExceptionTranslator().translate("Executing query", getSql(), se); } }
@Test public void testUsesCurrentTransaction() throws Exception { DataSource ds = mock(DataSource.class); Connection con = mock(Connection.class); when(con.getAutoCommit()).thenReturn(false); PreparedStatement ps = mock(PreparedStatement.class); when(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT)).thenReturn(ps); when(ds.getConnection()).thenReturn(con); when(ds.getConnection()).thenReturn(con); con.commit(); PlatformTransactionManager tm = new DataSourceTransactionManager(ds); TransactionTemplate tt = new TransactionTemplate(tm); final JdbcCursorItemReader<String> reader = new JdbcCursorItemReader<>(); reader.setDataSource(new ExtendedConnectionDataSourceProxy(ds)); reader.setUseSharedExtendedConnection(true); reader.setSql("select foo from bar"); final ExecutionContext ec = new ExecutionContext(); tt.execute( new TransactionCallback<Void>() { @Override public Void doInTransaction(TransactionStatus status) { reader.open(ec); reader.close(); return null; } }); }
final ExtendedConnectionDataSourceProxy csds = new ExtendedConnectionDataSourceProxy(ds); Connection con1 = csds.getConnection(); Connection con2 = csds.getConnection(); assertNotSame("shouldn't be the same connection", con1, con2); assertTrue("should be able to close connection", csds.shouldClose(con1)); con1.close(); assertTrue("should be able to close connection", csds.shouldClose(con2)); con2.close(); Connection con3 = csds.getConnection(); csds.startCloseSuppression(con3); Connection con3_1 = csds.getConnection(); assertSame("should be same connection", con3_1, con3); assertFalse("should not be able to close connection", csds.shouldClose(con3)); Connection con3_2 = csds.getConnection(); assertSame("should be same connection", con3_2, con3); Connection con4 = csds.getConnection(); assertNotSame("shouldn't be same connection", con4, con3); csds.stopCloseSuppression(con3); assertTrue("should be able to close connection", csds.shouldClose(con3)); con3_1 = null; con3_2 = null; con3.close(); assertTrue("should be able to close connection", csds.shouldClose(con4)); con4.close();
@Test public void unwrapForSmartDataSource() throws Exception { ExtendedConnectionDataSourceProxy tested = new ExtendedConnectionDataSourceProxy(new DataSourceStub()); assertTrue(tested.isWrapperFor(DataSource.class)); assertEquals(tested, tested.unwrap(DataSource.class)); assertTrue(tested.isWrapperFor(SmartDataSource.class)); assertEquals(tested, tested.unwrap(SmartDataSource.class)); }
/** * Close the cursor and database connection. Make call to cleanupOnClose so sub classes can cleanup * any resources they have allocated. */ @Override protected void doClose() throws Exception { initialized = false; JdbcUtils.closeResultSet(this.rs); rs = null; cleanupOnClose(); if(this.con != null) { this.con.setAutoCommit(this.initialConnectionAutoCommit); } if (useSharedExtendedConnection && dataSource instanceof ExtendedConnectionDataSourceProxy) { ((ExtendedConnectionDataSourceProxy)dataSource).stopCloseSuppression(this.con); if (!TransactionSynchronizationManager.isActualTransactionActive()) { DataSourceUtils.releaseConnection(con, dataSource); } } else { JdbcUtils.closeConnection(this.con); } }
protected void initializeConnection() { Assert.state(getDataSource() != null, "DataSource must not be null."); try { if (useSharedExtendedConnection) { if (!(getDataSource() instanceof ExtendedConnectionDataSourceProxy)) { throw new InvalidDataAccessApiUsageException( "You must use a ExtendedConnectionDataSourceProxy for the dataSource when " + "useSharedExtendedConnection is set to true."); } this.con = DataSourceUtils.getConnection(dataSource); ((ExtendedConnectionDataSourceProxy)dataSource).startCloseSuppression(this.con); } else { this.con = dataSource.getConnection(); } this.initialConnectionAutoCommit = this.con.getAutoCommit(); if (this.connectionAutoCommit != null && this.con.getAutoCommit() != this.connectionAutoCommit) { this.con.setAutoCommit(this.connectionAutoCommit); } } catch (SQLException se) { close(); throw getExceptionTranslator().translate("Executing query", getSql(), se); } }
TransactionTemplate tt = new TransactionTemplate(tm); final StoredProcedureItemReader<String> reader = new StoredProcedureItemReader<>(); reader.setDataSource(new ExtendedConnectionDataSourceProxy(ds)); reader.setUseSharedExtendedConnection(true); reader.setProcedureName("foo_bar");
@Test public void unwrapForUnsupportedInterface() throws Exception { ExtendedConnectionDataSourceProxy tested = new ExtendedConnectionDataSourceProxy(new DataSourceStub()); assertFalse(tested.isWrapperFor(Unsupported.class)); try { tested.unwrap(Unsupported.class); fail(); } catch (SQLException expected) { // this would be the correct behavior in a Java6-only recursive implementation // assertEquals(DataSourceStub.UNWRAP_ERROR_MESSAGE, expected.getMessage()); assertEquals("Unsupported class " + Unsupported.class.getSimpleName(), expected.getMessage()); } }
@Override public Connection getConnection(String username, String password) throws SQLException { synchronized (this.connectionMonitor) { return initConnection(username, password); } }
private boolean completeCloseCall(Connection connection) { if (borrowedConnection && closeSuppressedConnection.equals(connection)) { borrowedConnection = false; } return isCloseSuppressionActive(connection); }
private Connection initConnection(String username, String password) throws SQLException { if (closeSuppressedConnection != null) { if (!borrowedConnection) { borrowedConnection = true; return closeSuppressedConnection; } } Connection target; if (username != null) { target = dataSource.getConnection(username, password); } else { target = dataSource.getConnection(); } return getCloseSuppressingConnectionProxy(target); }
@Override public Connection getConnection() throws SQLException { synchronized (this.connectionMonitor) { return initConnection(null, null); } }