@Test public void testJtaTransactionWithConnectionHolderStillBound() throws Exception { @SuppressWarnings("serial") JtaTransactionManager ptm = new JtaTransactionManager(userTransaction) { @Override protected void doRegisterAfterCompletionWithJtaTransaction( JtaTransactionObject txObject, final List<TransactionSynchronization> synchronizations) throws RollbackException, SystemException { Thread async = new Thread() { @Override public void run() { invokeAfterCompletion(synchronizations, TransactionSynchronization.STATUS_COMMITTED); } }; async.start(); try { async.join(); } catch (InterruptedException ex) { ex.printStackTrace(); } } }; TransactionTemplate tt = new TransactionTemplate(ptm); assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dataSource)); assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); given(userTransaction.getStatus()).willReturn(Status.STATUS_ACTIVE); for (int i = 0; i < 3; i++) { final boolean releaseCon = (i != 1); tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) throws RuntimeException { assertTrue("JTA synchronizations active", TransactionSynchronizationManager.isSynchronizationActive()); assertTrue("Is existing transaction", !status.isNewTransaction()); Connection c = DataSourceUtils.getConnection(dataSource); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dataSource)); DataSourceUtils.releaseConnection(c, dataSource); c = DataSourceUtils.getConnection(dataSource); assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(dataSource)); if (releaseCon) { DataSourceUtils.releaseConnection(c, dataSource); } } }); if (!releaseCon) { assertTrue("Still has connection holder", TransactionSynchronizationManager.hasResource(dataSource)); } else { assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(dataSource)); } assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive()); } verify(connection, times(3)).close(); }