Browse Source

Cleanup after unexpected exception from external delegation call

Issue: SPR-17559
pull/2038/head
Juergen Hoeller 6 years ago
parent
commit
c024bdcc6f
  1. 7
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java
  2. 7
      spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java

7
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceUtils.java

@ -115,6 +115,7 @@ public abstract class DataSourceUtils {
Connection con = fetchConnection(dataSource); Connection con = fetchConnection(dataSource);
if (TransactionSynchronizationManager.isSynchronizationActive()) { if (TransactionSynchronizationManager.isSynchronizationActive()) {
try {
// Use same Connection for further JDBC actions within the transaction. // Use same Connection for further JDBC actions within the transaction.
// Thread-bound object will get removed by synchronization at transaction completion. // Thread-bound object will get removed by synchronization at transaction completion.
ConnectionHolder holderToUse = conHolder; ConnectionHolder holderToUse = conHolder;
@ -132,6 +133,12 @@ public abstract class DataSourceUtils {
TransactionSynchronizationManager.bindResource(dataSource, holderToUse); TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
} }
} }
catch (RuntimeException ex) {
// Unexpected exception from external delegation call -> close Connection and rethrow.
releaseConnection(con, dataSource);
throw ex;
}
}
return con; return con;
} }

7
spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java

@ -266,6 +266,7 @@ public abstract class EntityManagerFactoryUtils {
em = (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager()); em = (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager());
} }
try {
// Use same EntityManager for further JPA operations within the transaction. // Use same EntityManager for further JPA operations within the transaction.
// Thread-bound object will get removed by synchronization at transaction completion. // Thread-bound object will get removed by synchronization at transaction completion.
emHolder = new EntityManagerHolder(em); emHolder = new EntityManagerHolder(em);
@ -281,6 +282,12 @@ public abstract class EntityManagerFactoryUtils {
new TransactionScopedEntityManagerSynchronization(emHolder, emf)); new TransactionScopedEntityManagerSynchronization(emHolder, emf));
} }
TransactionSynchronizationManager.bindResource(emf, emHolder); TransactionSynchronizationManager.bindResource(emf, emHolder);
}
catch (RuntimeException ex) {
// Unexpected exception from external delegation call -> close EntityManager and rethrow.
closeEntityManager(em);
throw ex;
}
return em; return em;
} }

Loading…
Cancel
Save