Spring LDAP

org.springframework.ldap.transaction.compensating.manager
Class ContextSourceTransactionManager

java.lang.Object
  extended by org.springframework.transaction.support.AbstractPlatformTransactionManager
      extended by org.springframework.ldap.transaction.compensating.manager.ContextSourceTransactionManager
All Implemented Interfaces:
Serializable, InitializingBean, PlatformTransactionManager

public class ContextSourceTransactionManager
extends AbstractPlatformTransactionManager
implements InitializingBean

TransactionManager for managing LDAP transactions. Since transactions are not supported in the LDAP protocol, this class and its collaborators aim to provide compensating transactions instead. Should a transaction need to be rolled back, this TransactionManager will try to restore the original state using information recorded prior to each operation. The operation where the original state is restored is called a compensating operation.

NOTE: The transactions provided by this TransactionManager are all client side and are by no means 'real' transactions, in the sense that we know them in the ordinary database world, e.g.:

While the points above should be noted and considered, the compensating transaction approach will be perfectly sufficient for all but the most unfortunate of circumstances. Considering that there currently is a total absence of server-side transaction support in the LDAP world, being able to mark operations as transactional in the same way as for relational database operations is surely a step forward.

An LDAP transaction is tied to a ContextSource, to be supplied to the setContextSource(ContextSource) method. While the actual ContextSource used by the target LdapTemplate instance needs to be of the type TransactionAwareContextSourceProxy, the ContextSource supplied to this class should be the actual target ContextSource.

Using this TransactionManager along with TransactionAwareContextSourceProxy, all modifying operations (bind, unbind, rebind, rename, modifyAttributes) in a transaction will be intercepted. Each modification has its corresponding CompensatingTransactionOperationRecorder, which collects the information necessary to perform a rollback and produces a CompensatingTransactionOperationExecutor which is then used to execute the actual operation and is later called for performing the commit or rollback.

For several of the operations, performing a rollback is pretty straightforward. For example, in order to roll back a rename operation, it will only be required to rename the entry back to its original position. For other operations, however, it's a bit more complicated. An unbind operation is not possible to roll back by simply binding the entry back with the attributes retrieved from the original entry. It might not be possible to get all the information from the original entry. Consequently, the UnbindOperationExecutor will move the original entry to a temporary location in its performOperation() method. The commit() method will know that everything went well, so it will be OK to unbind the entry. The rollback operation will be to rename the entry back to its original location. The same behaviour is used for rebind() operations. The operation of calculating a temporary location for an entry is delegated to a TempEntryRenamingStrategy (default DefaultTempEntryRenamingStrategy), specified in setRenamingStrategy(TempEntryRenamingStrategy).

The actual work of this Transaction Manager is delegated to a ContextSourceTransactionManagerDelegate. This is because the exact same logic needs to be used if we want to wrap a JDBC and LDAP transaction in the same logical transaction.

Since:
1.2
Author:
Mattias Hellborg Arthursson
See Also:
ContextSourceAndDataSourceTransactionManager, ContextSourceTransactionManagerDelegate, DefaultCompensatingTransactionOperationManager, TempEntryRenamingStrategy, TransactionAwareContextSourceProxy, Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
AbstractPlatformTransactionManager.SuspendedResourcesHolder
 
Field Summary
 
Fields inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
logger, SYNCHRONIZATION_ALWAYS, SYNCHRONIZATION_NEVER, SYNCHRONIZATION_ON_ACTUAL_TRANSACTION
 
Constructor Summary
ContextSourceTransactionManager()
           
 
Method Summary
 void afterPropertiesSet()
           
protected  void doBegin(Object transaction, TransactionDefinition definition)
           
protected  void doCleanupAfterCompletion(Object transaction)
           
protected  void doCommit(DefaultTransactionStatus status)
           
protected  Object doGetTransaction()
           
protected  void doRollback(DefaultTransactionStatus status)
           
 ContextSource getContextSource()
          Get the ContextSource.
 void setContextSource(ContextSource contextSource)
          Set the ContextSource.
 void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy)
          Set the TempEntryRenamingStrategy.
 
Methods inherited from class org.springframework.transaction.support.AbstractPlatformTransactionManager
commit, determineTimeout, doResume, doSetRollbackOnly, doSuspend, getDefaultTimeout, getTransaction, getTransactionSynchronization, invokeAfterCompletion, isExistingTransaction, isFailEarlyOnGlobalRollbackOnly, isGlobalRollbackOnParticipationFailure, isNestedTransactionAllowed, isRollbackOnCommitFailure, isValidateExistingTransaction, newTransactionStatus, prepareForCommit, prepareSynchronization, prepareTransactionStatus, registerAfterCompletionWithExistingTransaction, resume, rollback, setDefaultTimeout, setFailEarlyOnGlobalRollbackOnly, setGlobalRollbackOnParticipationFailure, setNestedTransactionAllowed, setRollbackOnCommitFailure, setTransactionSynchronization, setTransactionSynchronizationName, setValidateExistingTransaction, shouldCommitOnGlobalRollbackOnly, suspend, triggerBeforeCommit, triggerBeforeCompletion, useSavepointForNestedTransaction
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ContextSourceTransactionManager

public ContextSourceTransactionManager()
Method Detail

doBegin

protected void doBegin(Object transaction,
                       TransactionDefinition definition)
                throws TransactionException
Specified by:
doBegin in class AbstractPlatformTransactionManager
Throws:
TransactionException

doCleanupAfterCompletion

protected void doCleanupAfterCompletion(Object transaction)
Overrides:
doCleanupAfterCompletion in class AbstractPlatformTransactionManager

doCommit

protected void doCommit(DefaultTransactionStatus status)
                 throws TransactionException
Specified by:
doCommit in class AbstractPlatformTransactionManager
Throws:
TransactionException

doGetTransaction

protected Object doGetTransaction()
                           throws TransactionException
Specified by:
doGetTransaction in class AbstractPlatformTransactionManager
Throws:
TransactionException

doRollback

protected void doRollback(DefaultTransactionStatus status)
                   throws TransactionException
Specified by:
doRollback in class AbstractPlatformTransactionManager
Throws:
TransactionException

getContextSource

public ContextSource getContextSource()
Get the ContextSource.

Returns:
the contextSource.
See Also:
ContextSourceTransactionManagerDelegate.getContextSource()

setContextSource

public void setContextSource(ContextSource contextSource)
Set the ContextSource.

Parameters:
contextSource - the ContextSource.
See Also:
ContextSourceTransactionManagerDelegate.setContextSource(ContextSource)

setRenamingStrategy

public void setRenamingStrategy(TempEntryRenamingStrategy renamingStrategy)
Set the TempEntryRenamingStrategy.

Parameters:
renamingStrategy - the Renaming Strategy.
See Also:
ContextSourceTransactionManagerDelegate.setRenamingStrategy(TempEntryRenamingStrategy)

afterPropertiesSet

public void afterPropertiesSet()
                        throws Exception
Specified by:
afterPropertiesSet in interface InitializingBean
Throws:
Exception

Spring LDAP