Only release rolled-back database savepoints during managed nested transaction

Issue: SPR-12228
This commit is contained in:
Juergen Hoeller 2014-09-19 00:11:44 +02:00
parent 0026d8faf8
commit 62340d6ccf
4 changed files with 29 additions and 22 deletions

View File

@ -127,12 +127,6 @@ public abstract class JdbcTransactionObjectSupport implements SavepointManager,
catch (Throwable ex) { catch (Throwable ex) {
throw new TransactionSystemException("Could not roll back to JDBC savepoint", 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);
}
} }
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.EntityManager;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import org.apache.commons.logging.LogFactory;
import org.apache.openjpa.persistence.OpenJPAEntityManager; import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAPersistence; import org.apache.openjpa.persistence.OpenJPAPersistence;
@ -103,7 +104,13 @@ public class OpenJpaDialect extends DefaultJpaDialect {
@Override @Override
public void releaseSavepoint(Object savepoint) throws TransactionException { 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);
}
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * Create a new savepoint. You can roll back to a specific savepoint
* via {@code rollbackToSavepoint}, and explicitly release a * via {@code rollbackToSavepoint}, and explicitly release a savepoint
* savepoint that you don't need anymore via {@code releaseSavepoint}. * that you don't need anymore via {@code releaseSavepoint}.
* <p>Note that most transaction managers will automatically release * <p>Note that most transaction managers will automatically release
* savepoints at transaction completion. * savepoints at transaction completion.
* @return a savepoint object, to be passed into rollbackToSavepoint * @return a savepoint object, to be passed into
* or releaseSavepoint * {@link #rollbackToSavepoint} or {@link #releaseSavepoint}
* @throws NestedTransactionNotSupportedException if the underlying * @throws NestedTransactionNotSupportedException if the underlying
* transaction does not support savepoints * transaction does not support savepoints
* @throws TransactionException if the savepoint could not be created, * @throws TransactionException if the savepoint could not be created,
@ -53,8 +53,10 @@ public interface SavepointManager {
Object createSavepoint() throws TransactionException; Object createSavepoint() throws TransactionException;
/** /**
* Roll back to the given savepoint. The savepoint will be * Roll back to the given savepoint.
* automatically released afterwards. * <p>The savepoint will <i>not</i> 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 * @param savepoint the savepoint to roll back to
* @throws NestedTransactionNotSupportedException if the underlying * @throws NestedTransactionNotSupportedException if the underlying
* transaction does not support savepoints * transaction does not support savepoints
@ -66,9 +68,9 @@ public interface SavepointManager {
/** /**
* Explicitly release the given savepoint. * Explicitly release the given savepoint.
* <p>Note that most transaction managers will automatically release * <p>Note that most transaction managers will automatically release
* savepoints at transaction completion. * savepoints on transaction completion.
* <p>Implementations should fail as silently as possible if * <p>Implementations should fail as silently as possible if proper
* proper resource cleanup will still happen at transaction completion. * resource cleanup will eventually happen at transaction completion.
* @param savepoint the savepoint to release * @param savepoint the savepoint to release
* @throws NestedTransactionNotSupportedException if the underlying * @throws NestedTransactionNotSupportedException if the underlying
* transaction does not support savepoints * transaction does not support savepoints

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public void rollbackToHeldSavepoint() throws TransactionException {
if (!hasSavepoint()) { 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().rollbackToSavepoint(getSavepoint());
getSavepointManager().releaseSavepoint(getSavepoint());
setSavepoint(null); setSavepoint(null);
} }
@ -160,7 +163,8 @@ public abstract class AbstractTransactionStatus implements TransactionStatus {
*/ */
public void releaseHeldSavepoint() throws TransactionException { public void releaseHeldSavepoint() throws TransactionException {
if (!hasSavepoint()) { 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()); getSavepointManager().releaseSavepoint(getSavepoint());
setSavepoint(null); setSavepoint(null);