From 146ac4123f54ad5816e7b34d05bf0808bb5c4fb0 Mon Sep 17 00:00:00 2001
From: Mattias Arthursson
- * A transaction is tied to a {@link ContextSource}, to be supplied to the
- * {@link #setContextSource(ContextSource)} method. While the actual
+ * 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, particularly considering the total absence of + * transaction support which is normally the case working against LDAP servers. + *
+ *+ * An LDAP transaction is tied to a {@link ContextSource}, to be supplied to + * the {@link #setContextSource(ContextSource)} method. While the actual * ContextSource used by the target LdapTemplate instance needs to be of the * type {@link TransactionAwareContextSourceProxy}, the ContextSource supplied * to this class should be the actual target ContextSource. *
*- * This class creates a {@link ContextSourceTransactionObject} as the - * implementation specific Transaction object. The actual transaction data is - * managed by a {@link DirContextHolder} and its collaborating - * {@link LdapCompensatingTransactionDataManager}. Using a - * {@link TransactionAwareContextSourceProxy} all modify operations (bind, - * rebind, modifyAttributes, unbind) will result in corresponding rollback - * operations to be recorded and these operations will be invoked should the - * transaction be rolled back. + * Using this TransactionManager along with + * {@link TransactionAwareContextSourceProxy} all modifying operations (bind, + * unbind, rebind, rename, modifyAttributes) in a transaction will be + * intercepted. Each modification has its corresponding + * {@link CompensatingTransactionOperationRecorder}, which collects the + * information necessary to perform a rollback and produces a + * {@link 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. E.g. 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. E.g. an unbind operation is + * not possible to roll back by simply binding the entry back with the + * attributes retrieved from the original entry. This is because it might not be + * possible to get all the information from the original entry. Consequently, + * the {@link UnbindOperationExecutor} will move the original entry to a + * temporary location in its performOperation() method. In the commit() method + * we already know that everything went well, so we're free to unbind the entry, + * but 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 + * {@link TempEntryRenamingStrategy} (default + * {@link DefaultTempEntryRenamingStrategy}), specified in + * {@link #setRenamingStrategy(TempEntryRenamingStrategy)}. *
* * @author Mattias Arthursson