Skip to content

Commit 9758bc7

Browse files
committed
Consistent reset of resource holders on doBegin failure
Issue: SPR-12280 (cherry picked from commit e58b33a)
1 parent c672678 commit 9758bc7

File tree

7 files changed

+35
-19
lines changed

7 files changed

+35
-19
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ protected Object doGetTransaction() {
179179
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
180180
txObject.setSavepointAllowed(isNestedTransactionAllowed());
181181
ConnectionHolder conHolder =
182-
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
182+
(ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
183183
txObject.setConnectionHolder(conHolder, false);
184184
return txObject;
185185
}
@@ -238,7 +238,10 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
238238
}
239239

240240
catch (Throwable ex) {
241-
DataSourceUtils.releaseConnection(con, this.dataSource);
241+
if (txObject.isNewConnectionHolder()) {
242+
DataSourceUtils.releaseConnection(con, this.dataSource);
243+
txObject.setConnectionHolder(null, false);
244+
}
242245
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
243246
}
244247
}

spring-jms/src/main/java/org/springframework/jms/connection/JmsTransactionManager.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -178,6 +178,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
178178
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
179179
throw new InvalidIsolationLevelException("JMS does not support an isolation level concept");
180180
}
181+
181182
JmsTransactionObject txObject = (JmsTransactionObject) transaction;
182183
Connection con = null;
183184
Session session = null;
@@ -193,10 +194,17 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
193194
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
194195
txObject.getResourceHolder().setTimeoutInSeconds(timeout);
195196
}
196-
TransactionSynchronizationManager.bindResource(
197-
getConnectionFactory(), txObject.getResourceHolder());
197+
TransactionSynchronizationManager.bindResource(getConnectionFactory(), txObject.getResourceHolder());
198198
}
199199
catch (Throwable ex) {
200+
if (session != null) {
201+
try {
202+
session.close();
203+
}
204+
catch (Throwable ex2) {
205+
// ignore
206+
}
207+
}
200208
if (con != null) {
201209
try {
202210
con.close();

spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/HibernateTransactionManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
513513
}
514514
finally {
515515
SessionFactoryUtils.closeSession(session);
516+
txObject.setSessionHolder(null);
516517
}
517518
}
518519
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);

spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -596,6 +596,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
596596
}
597597
finally {
598598
SessionFactoryUtils.closeSession(session);
599+
txObject.setSessionHolder(null);
599600
}
600601
}
601602
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);

spring-orm/src/main/java/org/springframework/orm/jdo/JdoTransactionManager.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -341,15 +341,16 @@ public int getTimeout() {
341341
conHolder.setTimeoutInSeconds(timeoutToUse);
342342
}
343343
if (logger.isDebugEnabled()) {
344-
logger.debug("Exposing JDO transaction as JDBC transaction [" + conHolder.getConnectionHandle() + "]");
344+
logger.debug("Exposing JDO transaction as JDBC transaction [" +
345+
conHolder.getConnectionHandle() + "]");
345346
}
346347
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
347348
txObject.setConnectionHolder(conHolder);
348349
}
349350
else {
350351
if (logger.isDebugEnabled()) {
351-
logger.debug("Not exposing JDO transaction [" + pm + "] as JDBC transaction because JdoDialect [" +
352-
getJdoDialect() + "] does not support JDBC Connection retrieval");
352+
logger.debug("Not exposing JDO transaction [" + pm + "] as JDBC transaction because " +
353+
"JdoDialect [" + getJdoDialect() + "] does not support JDBC Connection retrieval");
353354
}
354355
}
355356
}
@@ -391,6 +392,7 @@ protected void closePersistenceManagerAfterFailedBegin(JdoTransactionObject txOb
391392
finally {
392393
PersistenceManagerFactoryUtils.releasePersistenceManager(pm, getPersistenceManagerFactory());
393394
}
395+
txObject.setPersistenceManagerHolder(null, false);
394396
}
395397
}
396398

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,8 @@ protected Object doGetTransaction() {
331331
TransactionSynchronizationManager.getResource(getEntityManagerFactory());
332332
if (emHolder != null) {
333333
if (logger.isDebugEnabled()) {
334-
logger.debug("Found thread-bound EntityManager [" +
335-
emHolder.getEntityManager() + "] for JPA transaction");
334+
logger.debug("Found thread-bound EntityManager [" + emHolder.getEntityManager() +
335+
"] for JPA transaction");
336336
}
337337
txObject.setEntityManagerHolder(emHolder, false);
338338
}
@@ -400,15 +400,16 @@ public int getTimeout() {
400400
conHolder.setTimeoutInSeconds(timeoutToUse);
401401
}
402402
if (logger.isDebugEnabled()) {
403-
logger.debug("Exposing JPA transaction as JDBC transaction [" + conHolder.getConnectionHandle() + "]");
403+
logger.debug("Exposing JPA transaction as JDBC transaction [" +
404+
conHolder.getConnectionHandle() + "]");
404405
}
405406
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
406407
txObject.setConnectionHolder(conHolder);
407408
}
408409
else {
409410
if (logger.isDebugEnabled()) {
410-
logger.debug("Not exposing JPA transaction [" + em + "] as JDBC transaction because JpaDialect [" +
411-
getJpaDialect() + "] does not support JDBC Connection retrieval");
411+
logger.debug("Not exposing JPA transaction [" + em + "] as JDBC transaction because " +
412+
"JpaDialect [" + getJpaDialect() + "] does not support JDBC Connection retrieval");
412413
}
413414
}
414415
}
@@ -467,6 +468,7 @@ protected void closeEntityManagerAfterFailedBegin(JpaTransactionObject txObject)
467468
finally {
468469
EntityManagerFactoryUtils.closeEntityManager(em);
469470
}
471+
txObject.setEntityManagerHolder(null, false);
470472
}
471473
}
472474

spring-tx/src/main/java/org/springframework/jca/cci/connection/CciLocalTransactionManager.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -126,7 +126,7 @@ public Object getResourceFactory() {
126126
protected Object doGetTransaction() {
127127
CciLocalTransactionObject txObject = new CciLocalTransactionObject();
128128
ConnectionHolder conHolder =
129-
(ConnectionHolder) TransactionSynchronizationManager.getResource(getConnectionFactory());
129+
(ConnectionHolder) TransactionSynchronizationManager.getResource(getConnectionFactory());
130130
txObject.setConnectionHolder(conHolder);
131131
return txObject;
132132
}
@@ -159,7 +159,6 @@ protected void doBegin(Object transaction, TransactionDefinition definition) {
159159
}
160160
TransactionSynchronizationManager.bindResource(getConnectionFactory(), txObject.getConnectionHolder());
161161
}
162-
163162
catch (NotSupportedException ex) {
164163
ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
165164
throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex);
@@ -268,7 +267,7 @@ public void setConnectionHolder(ConnectionHolder connectionHolder) {
268267
}
269268

270269
public ConnectionHolder getConnectionHolder() {
271-
return connectionHolder;
270+
return this.connectionHolder;
272271
}
273272
}
274273

0 commit comments

Comments
 (0)