diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java index e5ae9df7cec..e2d1b0b917a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/JdbcTransactionObjectSupport.java @@ -127,12 +127,6 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager, catch (Throwable ex) { throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex); } - try { - conHolder.getConnection().releaseSavepoint((Savepoint) savepoint); - } - catch (Throwable ex) { - logger.debug("Could not explicitly release JDBC savepoint after rollback", ex); - } } /** diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java index 6cdebfe1417..f19b7ec8f94 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/OpenJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import java.sql.SQLException; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; +import org.apache.commons.logging.LogFactory; import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAPersistence; @@ -103,7 +104,13 @@ public class OpenJpaDialect extends DefaultJpaDialect { @Override public void releaseSavepoint(Object savepoint) throws TransactionException { - this.entityManager.releaseSavepoint((String) savepoint); + try { + this.entityManager.releaseSavepoint((String) savepoint); + } + catch (Throwable ex) { + LogFactory.getLog(OpenJpaTransactionData.class).debug( + "Could not explicitly release OpenJPA savepoint", ex); + } } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/SavepointManager.java b/spring-tx/src/main/java/org/springframework/transaction/SavepointManager.java index 56cb13e474d..9702a0f1ec4 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/SavepointManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/SavepointManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,12 +38,12 @@ public interface SavepointManager { /** * Create a new savepoint. You can roll back to a specific savepoint - * via {@code rollbackToSavepoint}, and explicitly release a - * savepoint that you don't need anymore via {@code releaseSavepoint}. + * via {@code rollbackToSavepoint}, and explicitly release a savepoint + * that you don't need anymore via {@code releaseSavepoint}. *

Note that most transaction managers will automatically release * savepoints at transaction completion. - * @return a savepoint object, to be passed into rollbackToSavepoint - * or releaseSavepoint + * @return a savepoint object, to be passed into + * {@link #rollbackToSavepoint} or {@link #releaseSavepoint} * @throws NestedTransactionNotSupportedException if the underlying * transaction does not support savepoints * @throws TransactionException if the savepoint could not be created, @@ -53,8 +53,10 @@ public interface SavepointManager { Object createSavepoint() throws TransactionException; /** - * Roll back to the given savepoint. The savepoint will be - * automatically released afterwards. + * Roll back to the given savepoint. + *

The savepoint will not be automatically released afterwards. + * You may explicitly call {@link #releaseSavepoint(Object)} or rely on + * automatic release on transaction completion. * @param savepoint the savepoint to roll back to * @throws NestedTransactionNotSupportedException if the underlying * transaction does not support savepoints @@ -66,9 +68,9 @@ public interface SavepointManager { /** * Explicitly release the given savepoint. *

Note that most transaction managers will automatically release - * savepoints at transaction completion. - *

Implementations should fail as silently as possible if - * proper resource cleanup will still happen at transaction completion. + * savepoints on transaction completion. + *

Implementations should fail as silently as possible if proper + * resource cleanup will eventually happen at transaction completion. * @param savepoint the savepoint to release * @throws NestedTransactionNotSupportedException if the underlying * transaction does not support savepoints diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractTransactionStatus.java b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractTransactionStatus.java index 840d7dbc493..1cfcda34cda 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/AbstractTransactionStatus.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/AbstractTransactionStatus.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -145,13 +145,16 @@ public abstract class AbstractTransactionStatus implements TransactionStatus { } /** - * Roll back to the savepoint that is held for the transaction. + * Roll back to the savepoint that is held for the transaction + * and release the savepoint right afterwards. */ public void rollbackToHeldSavepoint() throws TransactionException { if (!hasSavepoint()) { - throw new TransactionUsageException("No savepoint associated with current transaction"); + throw new TransactionUsageException( + "Cannot roll back to savepoint - no savepoint associated with current transaction"); } getSavepointManager().rollbackToSavepoint(getSavepoint()); + getSavepointManager().releaseSavepoint(getSavepoint()); setSavepoint(null); } @@ -160,7 +163,8 @@ public abstract class AbstractTransactionStatus implements TransactionStatus { */ public void releaseHeldSavepoint() throws TransactionException { if (!hasSavepoint()) { - throw new TransactionUsageException("No savepoint associated with current transaction"); + throw new TransactionUsageException( + "Cannot release savepoint - no savepoint associated with current transaction"); } getSavepointManager().releaseSavepoint(getSavepoint()); setSavepoint(null);