added "flush()" method to TransactionStatus and TransactionSynchronization interfaces; test context manager automatically flushes transactions before rolling back; general polishing of transaction management code
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -25,7 +25,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.jca.cci.CannotGetCciConnectionException;
|
||||
import org.springframework.transaction.support.ResourceHolder;
|
||||
import org.springframework.transaction.support.ResourceHolderSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -199,15 +198,16 @@ public abstract class ConnectionFactoryUtils {
|
||||
* Callback for resource cleanup at the end of a non-native CCI transaction
|
||||
* (e.g. when participating in a JTA transaction).
|
||||
*/
|
||||
private static class ConnectionSynchronization extends ResourceHolderSynchronization {
|
||||
private static class ConnectionSynchronization
|
||||
extends ResourceHolderSynchronization<ConnectionHolder, ConnectionFactory> {
|
||||
|
||||
public ConnectionSynchronization(ConnectionHolder connectionHolder, ConnectionFactory connectionFactory) {
|
||||
super(connectionHolder, connectionFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void releaseResource(ResourceHolder resourceHolder, Object resourceKey) {
|
||||
releaseConnection(((ConnectionHolder) resourceHolder).getConnection(), (ConnectionFactory) resourceKey);
|
||||
protected void releaseResource(ConnectionHolder resourceHolder, ConnectionFactory resourceKey) {
|
||||
releaseConnection(resourceHolder.getConnection(), resourceKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -75,6 +75,12 @@ public interface TransactionStatus extends SavepointManager {
|
||||
*/
|
||||
boolean isRollbackOnly();
|
||||
|
||||
/**
|
||||
* Flush the underlying session to the datastore, if applicable:
|
||||
* for example, all affected Hibernate/JPA sessions.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Return whether this transaction is completed, that is,
|
||||
* whether it has already been committed or rolled back.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -22,6 +22,7 @@ import javax.transaction.UserTransaction;
|
||||
|
||||
import org.springframework.transaction.TransactionSystemException;
|
||||
import org.springframework.transaction.support.SmartTransactionObject;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
|
||||
/**
|
||||
* JTA transaction object, representing a {@link javax.transaction.UserTransaction}.
|
||||
@@ -72,4 +73,13 @@ public class JtaTransactionObject implements SmartTransactionObject {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation triggers flush callbacks,
|
||||
* assuming that they will flush all affected ORM sessions.
|
||||
* @see org.springframework.transaction.support.TransactionSynchronization#flush()
|
||||
*/
|
||||
public void flush() {
|
||||
TransactionSynchronizationUtils.triggerFlush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -89,6 +89,12 @@ public abstract class AbstractTransactionStatus implements TransactionStatus {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementations is empty, considering flush as a no-op.
|
||||
*/
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this transaction as completed, that is, committed or rolled back.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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,7 +145,7 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
|
||||
/**
|
||||
* Determine the rollback-only flag via checking both the transaction object,
|
||||
* provided that the latter implements the SmartTransactionObject interface.
|
||||
* provided that the latter implements the {@link SmartTransactionObject} interface.
|
||||
* <p>Will return "true" if the transaction itself has been marked rollback-only
|
||||
* by the transaction coordinator, for example in case of a timeout.
|
||||
* @see SmartTransactionObject#isRollbackOnly
|
||||
@@ -156,6 +156,16 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
((SmartTransactionObject) this.transaction).isRollbackOnly());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate the flushing to the transaction object,
|
||||
* provided that the latter implements the {@link SmartTransactionObject} interface.
|
||||
*/
|
||||
public void flush() {
|
||||
if (this.transaction instanceof SmartTransactionObject) {
|
||||
((SmartTransactionObject) this.transaction).flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation exposes the SavepointManager interface
|
||||
* of the underlying transaction object, if any.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -23,11 +23,12 @@ package org.springframework.transaction.support;
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.5
|
||||
*/
|
||||
public class ResourceHolderSynchronization implements TransactionSynchronization {
|
||||
public abstract class ResourceHolderSynchronization<H extends ResourceHolder, K>
|
||||
implements TransactionSynchronization {
|
||||
|
||||
private final ResourceHolder resourceHolder;
|
||||
private final H resourceHolder;
|
||||
|
||||
private final Object resourceKey;
|
||||
private final K resourceKey;
|
||||
|
||||
private volatile boolean holderActive = true;
|
||||
|
||||
@@ -38,7 +39,7 @@ public class ResourceHolderSynchronization implements TransactionSynchronization
|
||||
* @param resourceKey the key to bind the ResourceHolder for
|
||||
* @see TransactionSynchronizationManager#bindResource
|
||||
*/
|
||||
public ResourceHolderSynchronization(ResourceHolder resourceHolder, Object resourceKey) {
|
||||
public ResourceHolderSynchronization(H resourceHolder, K resourceKey) {
|
||||
this.resourceHolder = resourceHolder;
|
||||
this.resourceKey = resourceKey;
|
||||
}
|
||||
@@ -56,6 +57,10 @@ public class ResourceHolderSynchronization implements TransactionSynchronization
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
flushResource(this.resourceHolder);
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
}
|
||||
|
||||
@@ -123,13 +128,20 @@ public class ResourceHolderSynchronization implements TransactionSynchronization
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush callback for the given resource holder.
|
||||
* @param resourceHolder the resource holder to flush
|
||||
*/
|
||||
protected void flushResource(H resourceHolder) {
|
||||
}
|
||||
|
||||
/**
|
||||
* After-commit callback for the given resource holder.
|
||||
* Only called when the resource hasn't been released yet
|
||||
* ({@link #shouldReleaseBeforeCompletion()}).
|
||||
* @param resourceHolder the resource holder to process
|
||||
*/
|
||||
protected void processResourceAfterCommit(ResourceHolder resourceHolder) {
|
||||
protected void processResourceAfterCommit(H resourceHolder) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +149,7 @@ public class ResourceHolderSynchronization implements TransactionSynchronization
|
||||
* @param resourceHolder the resource holder to process
|
||||
* @param resourceKey the key that the ResourceHolder was bound for
|
||||
*/
|
||||
protected void releaseResource(ResourceHolder resourceHolder, Object resourceKey) {
|
||||
protected void releaseResource(H resourceHolder, K resourceKey) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,7 +159,7 @@ public class ResourceHolderSynchronization implements TransactionSynchronization
|
||||
* @param committed whether the transaction has committed (<code>true</code>)
|
||||
* or rolled back (<code>false</code>)
|
||||
*/
|
||||
protected void cleanupResource(ResourceHolder resourceHolder, Object resourceKey, boolean committed) {
|
||||
protected void cleanupResource(H resourceHolder, K resourceKey, boolean committed) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -41,7 +41,7 @@ public class SimpleTransactionStatus extends AbstractTransactionStatus {
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link SimpleTransactionStatus} class,
|
||||
* Create a new instance of the {@link SimpleTransactionStatus} class,
|
||||
* indicating a new transaction.
|
||||
*/
|
||||
public SimpleTransactionStatus() {
|
||||
@@ -49,7 +49,7 @@ public class SimpleTransactionStatus extends AbstractTransactionStatus {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the {@link SimpleTransactionStatus} class.
|
||||
* Create a new instance of the {@link SimpleTransactionStatus} class.
|
||||
* @param newTransaction whether to indicate a new transaction
|
||||
*/
|
||||
public SimpleTransactionStatus(boolean newTransaction) {
|
||||
@@ -58,7 +58,7 @@ public class SimpleTransactionStatus extends AbstractTransactionStatus {
|
||||
|
||||
|
||||
public boolean isNewTransaction() {
|
||||
return newTransaction;
|
||||
return this.newTransaction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -39,4 +39,10 @@ public interface SmartTransactionObject {
|
||||
*/
|
||||
boolean isRollbackOnly();
|
||||
|
||||
/**
|
||||
* Flush the underlying sessions to the datastore, if applicable:
|
||||
* for example, all affected Hibernate/JPA sessions.
|
||||
*/
|
||||
void flush();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -27,7 +27,7 @@ import org.springframework.transaction.TransactionStatus;
|
||||
* @since 28.03.2003
|
||||
* @see TransactionTemplate
|
||||
*/
|
||||
public abstract class TransactionCallbackWithoutResult implements TransactionCallback {
|
||||
public abstract class TransactionCallbackWithoutResult implements TransactionCallback<Object> {
|
||||
|
||||
public final Object doInTransaction(TransactionStatus status) {
|
||||
doInTransactionWithoutResult(status);
|
||||
@@ -35,10 +35,10 @@ public abstract class TransactionCallbackWithoutResult implements TransactionCal
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets called by TransactionTemplate.execute within a transactional context.
|
||||
* Does not need to care about transactions itself, although it can retrieve
|
||||
* and influence the status of the current transaction via the given status
|
||||
* object, e.g. setting rollback-only.
|
||||
* Gets called by <code>TransactionTemplate.execute</code> within a transactional
|
||||
* context. Does not need to care about transactions itself, although it can retrieve
|
||||
* and influence the status of the current transaction via the given status object,
|
||||
* e.g. setting rollback-only.
|
||||
*
|
||||
* <p>A RuntimeException thrown by the callback is treated as application
|
||||
* exception that enforces a rollback. An exception gets propagated to the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -60,6 +60,13 @@ public interface TransactionSynchronization {
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* Flush the underlying session to the datastore, if applicable:
|
||||
* for example, a Hibernate/JPA session.
|
||||
* @see org.springframework.transaction.TransactionStatus#flush()
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/**
|
||||
* Invoked before transaction commit (before "beforeCompletion").
|
||||
* Can e.g. flush transactional O/R Mapping sessions to the database.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -42,6 +42,9 @@ public abstract class TransactionSynchronizationAdapter implements TransactionSy
|
||||
public void resume() {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
public void beforeCommit(boolean readOnly) {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
@@ -59,6 +59,17 @@ public abstract class TransactionSynchronizationUtils {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Trigger <code>flush</code> callbacks on all currently registered synchronizations.
|
||||
* @throws RuntimeException if thrown by a <code>flush</code> callback
|
||||
* @see TransactionSynchronization#flush()
|
||||
*/
|
||||
public static void triggerFlush() {
|
||||
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
|
||||
synchronization.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger <code>beforeCommit</code> callbacks on all currently registered synchronizations.
|
||||
* @param readOnly whether the transaction is defined as read-only transaction
|
||||
@@ -121,7 +132,7 @@ public abstract class TransactionSynchronizationUtils {
|
||||
* @see TransactionSynchronization#STATUS_UNKNOWN
|
||||
*/
|
||||
public static void triggerAfterCompletion(int completionStatus) {
|
||||
List synchronizations = TransactionSynchronizationManager.getSynchronizations();
|
||||
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
|
||||
invokeAfterCompletion(synchronizations, completionStatus);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user