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

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

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

Loading…
Cancel
Save