BackendConnection implements JDBCExecutionConnection { public synchronized Collection<SQLException> closeConnections(final boolean forceRollback) { Collection<SQLException> result = new LinkedList<>(); for (Connection each : cachedConnections.values()) { try { if (forceRollback && transactionStatus.isInTransaction()) { each.rollback(); } each.close(); } catch (final SQLException ex) { result.add(ex); } } cachedConnections.clear(); methodInvocations.clear(); connectionStatus.switchToReleased(); return result; } BackendConnection(final TransactionType initialTransactionType); void setCurrentSchema(final String schemaName); @Override List<Connection> getConnections(final String dataSourceName, final int connectionSize, final ConnectionMode connectionMode); @Override Statement createStorageResource(final Connection connection, final ConnectionMode connectionMode, final StatementOption option); @Override PreparedStatement createStorageResource(final String sql, final List<Object> parameters, 
                                                   final Connection connection, final ConnectionMode connectionMode, final StatementOption option); boolean isSerialExecute(); int getConnectionSize(); void add(final Statement statement); void add(final ResultSet resultSet); synchronized Collection<SQLException> closeResultSets(); synchronized Collection<SQLException> closeStatements(); synchronized Collection<SQLException> closeConnections(final boolean forceRollback);  }
@Test public void assertCloseConnectionsCorrectlyWhenNotForceRollback() throws NoSuchFieldException, IllegalAccessException, SQLException { Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); field.setAccessible(true); Multimap<String, Connection> cachedConnections = (Multimap<String, Connection>) field.get(backendConnection); Connection connection = prepareCachedConnections(); cachedConnections.put("ignoredDataSourceName", connection); ConnectionStatus connectionStatus = mock(ConnectionStatus.class); prepareConnectionStatus(connectionStatus); backendConnection.closeConnections(false); verify(connection, times(1)).close(); assertTrue(cachedConnections.isEmpty()); verifyMethodInvocationsEmpty(); verify(connectionStatus, times(1)).switchToReleased(); }
@Test public void assertCloseConnectionsCorrectlyWhenForceRollbackAndNotInTransaction() throws SQLException { ConnectionStatus connectionStatus = mock(ConnectionStatus.class); prepareConnectionStatus(connectionStatus); backendConnection.getTransactionStatus().setInTransaction(false); Connection connection = prepareCachedConnections(); backendConnection.closeConnections(true); verify(connection, never()).rollback(); verify(connectionStatus, times(1)).switchToReleased(); }
@Test public void assertCloseConnectionsCorrectlyWhenForceRollbackAndInTransaction() throws SQLException { ConnectionStatus connectionStatus = mock(ConnectionStatus.class); prepareConnectionStatus(connectionStatus); backendConnection.getTransactionStatus().setInTransaction(true); Connection connection = prepareCachedConnections(); backendConnection.closeConnections(true); verify(connection, times(1)).rollback(); verify(connectionStatus, times(1)).switchToReleased(); }
@Test public void assertCloseConnectionsCorrectlyWhenSQLExceptionThrown() throws SQLException { ConnectionStatus connectionStatus = mock(ConnectionStatus.class); prepareConnectionStatus(connectionStatus); Connection connection = prepareCachedConnections(); SQLException sqlException = new SQLException(""); doThrow(sqlException).when(connection).close(); assertTrue(backendConnection.closeConnections(false).contains(sqlException)); }