交易支持
习惯使用关系型数据库的程序员进入LDAP领域时,常常对它没有交易概念感到惊讶。 协议中未明确规定,且没有任何LDAP服务器支持该功能。 意识到这可能是一个重大问题,Spring LDAP 为客户端提供支持,并补偿 LDAP 资源上的事务。
LDAP 事务支持 由ContextSourceTransactionManager一个PlatformTransactionManager该实现管理 LDAP作的 Spring 事务支持。它与合作者一起跟踪事务中执行的LDAP作,在每次作前记录状态,并在需要回滚事务时采取措施恢复初始状态。
除了实际的事务管理外,Spring LDAP 的事务支持还确保了同样的作DirContext实例在同一交易中被使用。也就是说,DirContext直到交易完成后才会真正关闭,从而实现更高效的资源使用。
| 虽然 Spring LDAP 用于提供交易支持的方法在许多情况下已足够,但它绝非传统意义上的“真实”事务。 服务器完全不知道这些交易,所以(例如)如果连接断开,就无法回滚交易。 虽然这需要谨慎考虑,但也应注意,另一种选择是完全不依赖任何交易支持。Spring LDAP的交易支持几乎是最好的。 |
客户端事务支持除了原有作所需的工作外,还增加了一些开销。
虽然这种开销在大多数情况下无需担心,
如果您的应用程序在同一事务中不执行多个 LDAP作(例如,modifyAttributes其次重新绑定),
或者如果不需要与 JDBC 数据源的事务同步(参见 JDBC 事务集成),使用 LDAP 事务支持几乎没有带来什么好处。 |
配置
如果你习惯配置 Spring 事务,配置 Spring 的 LDAP 事务应该会很熟悉。你可以用@Transactional,创建一个事务管理器实例,并包含一个<tx:注释驱动>你豆子配置中的元素。以下示例展示了如何实现:
<ldap:context-source
url="ldap://localhost:389"
base="dc=example,dc=com"
username="cn=Manager"
password="secret" />
<ldap:ldap-template id="ldapTemplate" />
<ldap:transaction-manager>
<!--
Note this default configuration will not work for more complex scenarios;
see below for more information on RenamingStrategies.
-->
<ldap:default-renaming-strategy />
</ldap:transaction-manager>
<!--
The MyDataAccessObject class is annotated with @Transactional.
-->
<bean id="myDataAccessObject" class="com.example.MyRepository">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
<tx:annotation-driven />
...
虽然这种配置在大多数简单场景下运行良好,但一些更复杂的场景需要额外配置。
具体来说,如果你需要在事务中创建或删除子树,你需要使用替代方案临时条目重命名策略,如《重命名策略》中所述。 |
在现实中,你可能会把事务应用到服务对象层面,而不是仓库层面。前面的例子说明了这一大致的思路。
LDAP补偿交易解析
Spring LDAP 通过在每次修改作前在 LDAP 树中记录状态来管理补偿事务(捆,㩠,重新绑定,modifyAttributes和重命名). 这使得系统能够在需要回滚事务时执行补偿作。
在许多情况下,补偿作相当直接。例如,补偿回滚作对于捆作是解绑条目。然而,其他作由于LDAP数据库的一些特殊特性,需要不同且更复杂的方法。具体来说,并非总能获得所有的值属性使得上述策略对(例如)㩠操作。
这就是为什么在 Spring LDAP 管理事务中执行的每个修改作内部都分为四个不同的作:记录作,准备作、提交作和回滚作。下表描述了每个 LDAP作:
| LDAP作 | 录音 | 制备 | 犯 | 反转 |
|---|---|---|---|---|
|
记录条目的DN以便绑定。 |
装订条目。 |
没有手术。 |
使用记录的DN解绑条目。 |
|
记录原始DN和目标DN。 |
重新命名条目。 |
没有手术。 |
将条目重命名回原DN。 |
|
记录原始DN,并计算临时DN。 |
将条目重新命名为临时地点。 |
解除临时条纹的绑定。 |
将临时位置的条目重命名为原DN。 |
|
记录原始DN和新DN |
将条目重命名为临时地点。 |
绑定新 |
将临时位置的条目重命名为原DN。 |
|
记录条目的DN以便修改和计算补偿 |
执行 |
没有手术。 |
执行一个 |
Javadoc 中提供了 Spring LDAP 事务支持内部运作的更详细描述。
更名策略
如前一节表格所述,某些作的事务管理要求在提交中进行实际修改前,先暂时重命名受该作影响的原始条目。条目临时DN的计算方式由临时条目重命名策略即在 的子元素中指定<ldap:transaction-manager >在配置中声明。Spring LDAP 包含两种实现:
-
DefaultTempEntryRenameingStrategy(默认情况):通过使用<ldap:default-renaming-strategy />元素。 在条目 DN 的最低有效部分加一个后缀。例如,对于cn=约翰·多,ou=用户该策略返回一个临时DNcn=约翰·doe_temp,ou=用户. 你可以通过设置临时后缀属性。 -
不同的子树TempEntryRenamingStrategy:通过使用<ldap:different-subtree-renameing-strategy />元素。 它将子树 DN 附加到该 DN 的最低有效部分。这样做使所有临时条目被放置在 LDAP 树中的特定位置。临时子树 DN 的配置是通过设置子树节点属性。 例如,如果子树节点是ou=temp条目而该条目的原始DN为cn=约翰·多,ou=用户,临时DN为cn=约翰·多,ou=tempEntries. 注意,配置后的子树节点必须存在于LDAP树中。
这DefaultTempEntryRenameingStrategy在某些情况下,这并不起作用。例如,如果你计划进行递归删除,你需要使用不同的子树TempEntryRenamingStrategy. 这是因为递归删除作实际上是对子树中每个节点进行深度优先的单独删除。因为你无法重命名包含任何子节点和DefaultTempEntryRenameingStrategy如果会让每个节点都留在同一个子树(但名称不同),而不是真正移除它,这个作就会失败。有疑问时,使用不同的子树TempEntryRenamingStrategy. |