Skip to content

Commit 792991a

Browse files
committed
Cleanup after unexpected exception from external delegation call
Issue: SPR-17559 (cherry picked from commit c024bdc)
1 parent b8480ea commit 792991a

File tree

2 files changed

+41
-27
lines changed

2 files changed

+41
-27
lines changed

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

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,28 @@ public static Connection doGetConnection(DataSource dataSource) throws SQLExcept
111111
Connection con = dataSource.getConnection();
112112

113113
if (TransactionSynchronizationManager.isSynchronizationActive()) {
114-
// Use same Connection for further JDBC actions within the transaction.
115-
// Thread-bound object will get removed by synchronization at transaction completion.
116-
ConnectionHolder holderToUse = conHolder;
117-
if (holderToUse == null) {
118-
holderToUse = new ConnectionHolder(con);
119-
}
120-
else {
121-
holderToUse.setConnection(con);
114+
try {
115+
// Use same Connection for further JDBC actions within the transaction.
116+
// Thread-bound object will get removed by synchronization at transaction completion.
117+
ConnectionHolder holderToUse = conHolder;
118+
if (holderToUse == null) {
119+
holderToUse = new ConnectionHolder(con);
120+
}
121+
else {
122+
holderToUse.setConnection(con);
123+
}
124+
holderToUse.requested();
125+
TransactionSynchronizationManager.registerSynchronization(
126+
new ConnectionSynchronization(holderToUse, dataSource));
127+
holderToUse.setSynchronizedWithTransaction(true);
128+
if (holderToUse != conHolder) {
129+
TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
130+
}
122131
}
123-
holderToUse.requested();
124-
TransactionSynchronizationManager.registerSynchronization(
125-
new ConnectionSynchronization(holderToUse, dataSource));
126-
holderToUse.setSynchronizedWithTransaction(true);
127-
if (holderToUse != conHolder) {
128-
TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
132+
catch (RuntimeException ex) {
133+
// Unexpected exception from external delegation call -> close Connection and rethrow.
134+
releaseConnection(con, dataSource);
135+
throw ex;
129136
}
130137
}
131138

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

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -285,21 +285,28 @@ else if (!TransactionSynchronizationManager.isSynchronizationActive()) {
285285
em = (!CollectionUtils.isEmpty(properties) ? emf.createEntityManager(properties) : emf.createEntityManager());
286286
}
287287

288-
// Use same EntityManager for further JPA operations within the transaction.
289-
// Thread-bound object will get removed by synchronization at transaction completion.
290-
emHolder = new EntityManagerHolder(em);
291-
if (synchronizedWithTransaction) {
292-
Object transactionData = prepareTransaction(em, emf);
293-
TransactionSynchronizationManager.registerSynchronization(
294-
new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, true));
295-
emHolder.setSynchronizedWithTransaction(true);
288+
try {
289+
// Use same EntityManager for further JPA operations within the transaction.
290+
// Thread-bound object will get removed by synchronization at transaction completion.
291+
emHolder = new EntityManagerHolder(em);
292+
if (synchronizedWithTransaction) {
293+
Object transactionData = prepareTransaction(em, emf);
294+
TransactionSynchronizationManager.registerSynchronization(
295+
new TransactionalEntityManagerSynchronization(emHolder, emf, transactionData, true));
296+
emHolder.setSynchronizedWithTransaction(true);
297+
}
298+
else {
299+
// Unsynchronized - just scope it for the transaction, as demanded by the JPA 2.1 spec...
300+
TransactionSynchronizationManager.registerSynchronization(
301+
new TransactionScopedEntityManagerSynchronization(emHolder, emf));
302+
}
303+
TransactionSynchronizationManager.bindResource(emf, emHolder);
296304
}
297-
else {
298-
// Unsynchronized - just scope it for the transaction, as demanded by the JPA 2.1 spec...
299-
TransactionSynchronizationManager.registerSynchronization(
300-
new TransactionScopedEntityManagerSynchronization(emHolder, emf));
305+
catch (RuntimeException ex) {
306+
// Unexpected exception from external delegation call -> close EntityManager and rethrow.
307+
closeEntityManager(em);
308+
throw ex;
301309
}
302-
TransactionSynchronizationManager.bindResource(emf, emHolder);
303310

304311
return em;
305312
}

0 commit comments

Comments
 (0)