Compensating rollback operations are now not stored until the target operation has been successfully performed.

This commit is contained in:
Mattias Arthursson
2007-01-06 16:49:29 +00:00
parent 9d59e1fd29
commit 4a8541ae2e
10 changed files with 79 additions and 34 deletions

View File

@@ -46,9 +46,9 @@ public class BindRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
Name dn = LdapUtils.getFirstArgumentAsName(args);
return new UnbindRollbackOperation(ldapOperations, dn);

View File

@@ -25,16 +25,16 @@ package org.springframework.ldap.support.transaction;
*/
public interface CompensatingTransactionDataManager {
/**
* Indicates that the supplied operation (method name) has been invoked with
* the specified parameters. This method is called just prior the the actual
* invocation of the target method.
* Indicates that the supplied operation (method name) has been performed
* and that the supplied {@link CompensatingTransactionRollbackOperation}
* should be stored for possible rollback. This method is called after the
* the actual invocation of the target method.
*
* @param operation
* the method to be invoked.
* @param params
* arguments supplied to the operation.
*/
public void operationPerformed(String operation, Object[] params);
public void operationPerformed(
CompensatingTransactionRollbackOperation operation);
/**
* Rollback all recorded operations, by performing each of the recorded

View File

@@ -34,6 +34,8 @@ public class DirContextHolder extends ResourceHolderSupport {
private CompensatingTransactionDataManager transactionDataManager;
private CompensatingTransactionOperationFactory operationFactory;
/**
* Constructor.
*
@@ -42,7 +44,8 @@ public class DirContextHolder extends ResourceHolderSupport {
*/
public DirContextHolder(DirContext ctx) {
this.ctx = ctx;
this.transactionDataManager = new LdapCompensatingTransactionDataManager(
this.transactionDataManager = new DefaultCompensatingTransactionDataManager();
this.operationFactory = new LdapCompensatingTransactionOperationFactory(
ctx);
}
@@ -54,7 +57,8 @@ public class DirContextHolder extends ResourceHolderSupport {
*/
public void setCtx(DirContext ctx) {
this.ctx = ctx;
this.transactionDataManager = new LdapCompensatingTransactionDataManager(
this.transactionDataManager = new DefaultCompensatingTransactionDataManager();
this.operationFactory = new LdapCompensatingTransactionOperationFactory(
ctx);
}
@@ -70,6 +74,7 @@ public class DirContextHolder extends ResourceHolderSupport {
public void clear() {
super.clear();
transactionDataManager = null;
operationFactory = null;
}
/**
@@ -92,4 +97,8 @@ public class DirContextHolder extends ResourceHolderSupport {
CompensatingTransactionDataManager transactionDataManager) {
this.transactionDataManager = transactionDataManager;
}
public CompensatingTransactionOperationFactory getOperationFactory() {
return operationFactory;
}
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.ldap.support.transaction;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
@@ -131,23 +134,51 @@ public class LdapUtils {
/**
* Store compensating transaction data for the supplied operation and
* arguments.
* arguments. TODO: Clean up this mess.
*
* @param contextSource
* the ContextSource we are operating on.
* @param methodName
* @param method
* name of the method to be invoked.
* @param args
* arguments with which the operation is invoked.
*/
public static void storeCompensatingTransactionData(
ContextSource contextSource, String methodName, Object[] args) {
public static Object operationPerformed(ContextSource contextSource,
Method method, Object[] args) throws Throwable {
DirContextHolder transactionContextHolder = (DirContextHolder) TransactionSynchronizationManager
.getResource(contextSource);
if (transactionContextHolder != null) {
CompensatingTransactionDataManager transactionDataManager = transactionContextHolder
.getTransactionDataManager();
transactionDataManager.operationPerformed(methodName, args);
CompensatingTransactionOperationFactory operationFactory = transactionContextHolder
.getOperationFactory();
// Record the operation
CompensatingTransactionRecordingOperation operation = operationFactory
.createRecordingOperation(method.getName());
CompensatingTransactionRollbackOperation rollbackOperation = operation
.recordOperation(args);
Object result = null;
// Perform the target operation
try {
result = method.invoke(transactionContextHolder.getCtx(), args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
transactionDataManager.operationPerformed(rollbackOperation);
return result;
} else {
Object result = null;
// Perform the target operation
try {
result = method.invoke(transactionContextHolder.getCtx(), args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
return result;
}
}
}

View File

@@ -49,9 +49,9 @@ public class ModifyAttributesRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
Assert.notNull(args);
Name dn = LdapUtils.getFirstArgumentAsName(args);

View File

@@ -31,9 +31,9 @@ public class NullRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
return new NullRollbackOperation();
}

View File

@@ -25,7 +25,7 @@ import org.springframework.ldap.support.DirContextAdapter;
/**
* A {@link CompensatingTransactionRecordingOperation} keeping track of a rebind
* operation. Creates {@link RebindRollbackOperation} objects in
* {@link #performOperation(Object[])}.
* {@link #recordOperation(Object[])}.
*
* @author Mattias Arthursson
*/
@@ -50,9 +50,9 @@ public class RebindRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
Name dn = LdapUtils.getFirstArgumentAsName(args);

View File

@@ -51,9 +51,9 @@ public class RenameRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
log.debug("Storing rollback information for rename operation");
Assert.notEmpty(args);

View File

@@ -52,6 +52,12 @@ public class TransactionAwareDirContextInvocationHandler implements
this.contextSource = contextSource;
}
/*
* (non-Javadoc)
*
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
@@ -69,14 +75,13 @@ public class TransactionAwareDirContextInvocationHandler implements
return null;
} else if (LdapUtils.isSupportedWriteTransactionOperation(methodName)) {
// Store transaction data and allow operation to proceed.
LdapUtils.storeCompensatingTransactionData(contextSource,
methodName, args);
}
try {
return method.invoke(target, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
return LdapUtils.operationPerformed(contextSource, method, args);
} else {
try {
return method.invoke(target, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
}
}

View File

@@ -47,9 +47,9 @@ public class UnbindRecordingOperation implements
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#performOperation(java.lang.Object[])
* @see org.springframework.ldap.support.transaction.CompensatingTransactionRecordingOperation#recordOperation(java.lang.Object[])
*/
public CompensatingTransactionRollbackOperation performOperation(
public CompensatingTransactionRollbackOperation recordOperation(
Object[] args) {
Name dn = LdapUtils.getFirstArgumentAsName(args);
DirContextAdapter ctx = (DirContextAdapter) ldapOperations.lookup(dn);