Started documentation of transactions.

This commit is contained in:
Mattias Arthursson
2007-02-27 19:43:55 +00:00
parent 9d1e50a17d
commit 8cc110e857
2 changed files with 103 additions and 0 deletions

View File

@@ -8,6 +8,7 @@
<!ENTITY dirobjectfactory SYSTEM "dirobjectfactory.xml">
<!ENTITY executors SYSTEM "executors.xml">
<!ENTITY contextprocessor SYSTEM "contextprocessor.xml">
<!ENTITY transactions SYSTEM "transactions.xml">
<!ENTITY configuration SYSTEM "configuration.xml">
]>
@@ -45,6 +46,7 @@
&overview;
&basic;
&dirobjectfactory;
&transactions;
&executors;
&contextprocessor;
&configuration;

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="transactions">
<title>LDAP Transaction Support</title>
<sect1 id="transactions-intro">
<title>Introduction</title>
<para>Programmers used to working with relational databases coming to the LDAP
world often express surprise to the fact that there is no notion of transactions.
It is not specified in the protocol, and thus no servers support it.
Recognizing that this is a major problem, Spring LDAP provides support for client-side,
compensating transactions on LDAP resources.
</para>
<para>LDAP transaction support is provided by <literal>ContextSourceTransactionManager</literal>, a
<literal>PlatformTransactionManager</literal> implementation that manages Spring transaction
support for LDAP operations. Along with its collaborators it keeps track of the LDAP operations
performed in a transaction, making record of the state before each operation and taking steps to
restore the initial state should the transaction need to be rolled back.
<note>It is important to note that while the above approach is sufficient for many cases,
it is by no means &quot;real&quot; transactions in the traditional sense. The server is completely
unaware of the transactions, so e.g. if the connection is broken there will be no hope to rollback
the transaction. While the above should be carefully considered it should also be noted
that the alternative will be to operate without any transaction support whatsoever; this is pretty much
as good as it gets.</note>
</para>
</sect1>
<sect1 id="transactions-configuration">
<title>Configuration</title>
<para>
Configuring Spring LDAP transactions should look very familiar if you're used to configuring Spring transactions.
You will create a <literal>TransactionManager</literal> instance and wrap your target object using a
<literal>TransactionProxyFactoryBean</literal>. In addition to this, you will also need to wrap your
<literal>ContextSource</literal> in a <literal>TransactionAwareContextSourceProxy</literal>.
<informalexample>
<programlisting>&lt;beans&gt;
...
&lt;bean id="contextSourceTarget" class="org.springframework.ldap.core.support.LdapContextSource"&gt;
&lt;property name="url" value="ldap://localhost:389" /&gt;
&lt;property name="base" value="dc=example,dc=com" /&gt;
&lt;property name="userDn" value="cn=Manager" /&gt;
&lt;property name="password" value="secret" /&gt;
&lt;/bean&gt;
&lt;bean id="contextSource"
class="org.springframework.ldap.transaction.core.TransactionAwareContextSourceProxy"&gt;
&lt;constructor-arg ref="contextSourceTarget" /&gt;
&lt;/bean&gt;
&lt;bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"&gt;
&lt;constructor-arg ref="contextSource" /&gt;
&lt;/bean&gt;
&lt;bean id="transactionManager"
class="org.springframework.ldap.transaction.core.ContextSourceTransactionManager"&gt;
&lt;constructor-arg ref="contextSource" /&gt;
&lt;/bean&gt;
&lt;bean id="myDataAccessObjectTarget" class="com.example.MyDataAccessObject"&gt;
&lt;property name="ldapTemplate" ref="ldapTemplate" /&gt;
&lt;/bean&gt;
&lt;bean id="myDataAccessObject"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
&lt;property name="transactionManager" ref="transactionManager" /&gt;
&lt;property name="target" ref="myDataAccessObjectTarget" /&gt;
&lt;property name="transactionAttributes"&gt;
&lt;props&gt;
&lt;prop key="*"&gt;PROPAGATION_REQUIRES_NEW&lt;/prop&gt;
&lt;/props&gt;
&lt;/property&gt;
&lt;/bean&gt;
...</programlisting>
</informalexample>
In a real world example you would probably apply the transactions on the service object level
rather than the DAO level; the above serves as an example to demonstrate the general idea.
<note>You'll notice that the actual <literal>ContextSource</literal> and DAO instances get ids with a
&quot;Target&quot; suffix. The beans you will actually refer to are the Proxies that are created
around the targets; <literal>contextSource</literal> and <literal>myDataAccessObject</literal></note>
</para>
</sect1>
<sect1>
<title>The Inner Workings</title>
<para>In order to properly benefit from the Spring LDAP transaction support it will be useful to know
something about the inner workings. At the heart of the LDAP transaction support, of course, there
is the <literal>ContextSourceTransactionManager</literal>. This works in close collaboration with
a <literal>CompensatingTransactionOperationManager</literal> instance, which is tied to the transaction
by the TransactionManager. Using the <literal>TransactionAwareContextSourceProxy</literal> causes
all modifying operations to be forwarded to the <literal>CompensatingTransactionOperationManager</literal>,
which &quot;records&quot; the state before the operation and gets a <literal>CompensatingTransactionOperationExecutor</literal>
for the specific operation. One OperationExecutor is responsible for executing and committing or rolling back
one single operation, and OperationManager manages a sequence of OperationExecutors representing all operations
within a transaction.</para>
<para>Now, the <literal>CompensatingTransactionOperationExecutor</literal> knows the relevant state before the operation
was performed.
</para>
</sect1>
</chapter>