|
此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring LDAP 3.3.3! |
交易支持
习惯于使用 LDAP 世界的关系数据库的程序员经常对没有事务概念这一事实表示惊讶。 协议中未指定它,并且没有 LDAP 服务器支持它。 认识到这可能是一个主要问题,Spring LDAP 为客户端提供了对 LDAP 资源的补偿事务的支持。
LDAP 事务支持由ContextSourceTransactionManager一个PlatformTransactionManager管理 LDAP作的 Spring 事务支持的实现。它与其合作者一起跟踪事务中执行的 LDAP作,记录每次作之前的状态,并在事务需要回滚时采取措施恢复初始状态。
除了实际的事务管理外,Spring LDAP 事务支持还确保了DirContext实例在同一事务中使用。也就是说,DirContext在事务完成之前实际上不会关闭,从而可以更有效地利用资源。
| 虽然 Spring LDAP 用于提供事务支持的方法在许多情况下已经足够了,但它绝不是传统意义上的“真实”事务。 服务器完全不知道事务,因此(例如),如果连接中断,则无法回滚事务。 虽然应该仔细考虑这一点,但还应该注意的是,另一种选择是在没有任何交易支持的情况下进行作。Spring LDAP 的事务支持几乎是最好的。 |
除了原始作所需的工作之外,客户端事务支持还增加了一些开销。
虽然在大多数情况下,这种开销不应该是值得担心的事情,
如果您的应用程序未在同一事务中执行多个 LDAP作(例如,modifyAttributes其次rebind),
或者,如果不需要与 JDBC 数据源进行事务同步(参见 JDBC 事务集成),那么使用 LDAP 事务支持几乎没有什么好处。 |
配置
如果您习惯于配置 Spring 事务,那么配置 Spring LDAP 事务应该看起来非常熟悉。您可以使用@Transactional,创建一个TransactionManager实例,并包含一个<tx:annotation-driven>元素。以下示例显示了如何执行此作:
<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 />
...
虽然此设置适用于大多数简单的用例,但一些更复杂的场景需要额外的配置。
具体来说,如果您需要在事务中创建或删除子树,则需要使用替代方法TempEntryRenamingStrategy,如重命名策略中所述。 |
在实际情况下,您可能会在服务对象级别而不是存储库级别应用事务。前面的示例演示了一般思想。
LDAP 补偿事务说明
Spring LDAP 通过在每次修改作(bind,unbind,rebind,modifyAttributes和rename).
这允许系统在需要回滚事务时执行补偿作。
在许多情况下,补偿作非常简单。例如,对bind作是解绑条目。
但是,由于 LDAP 数据库的一些特殊特征,其他作需要不同的、更复杂的方法。
具体来说,并不总是能够获得所有Attributes,使得上述策略不足以(例如)一个unbind操作。
这就是为什么在 Spring LDAP 托管事务中执行的每个修改作在内部都分为四个不同的作:记录作、 准备作、提交作和回滚作。下表描述了每个 LDAP作:
| LDAP作 | 录音 | 制备 | 犯 | 反转 |
|---|---|---|---|---|
|
记录要绑定的条目的DN。 |
绑定条目。 |
没有作。 |
使用记录的 DN 取消绑定条目。 |
|
记录原始 DN 和目标 DN。 |
重命名条目。 |
没有作。 |
将条目重命名回其原始 DN。 |
|
记录原始DN并计算临时DN。 |
将条目重命名为临时位置。 |
解绑临时条目。 |
将条目从临时位置重命名回其原始 DN。 |
|
记录原始 DN 和新 |
将条目重命名为临时位置。 |
绑定新的 |
将条目从临时位置重命名回其原始 DN。 |
|
记录条目的DN以修改和计算补偿 |
执行 |
没有作。 |
执行 |
Javadoc 中提供了 Spring LDAP 事务支持的内部工作原理的更详细描述。
重命名策略
如上一节的表所述,某些作的事务管理需要暂时重命名受作影响的原始条目,然后才能在提交中进行实际修改。计算条目的临时 DN 的方式由TempEntryRenamingStrategy在<ldap:transaction-manager >声明。Spring LDAP 包括两个实现:
-
DefaultTempEntryRenamingStrategy(默认值):通过使用<ldap:default-renaming-strategy />元素。向条目 DN 的最低有效部分添加后缀。例如,对于 DN 为cn=john doe, ou=users,则此策略返回临时 DNcn=john doe_temp, ou=users.您可以通过设置temp-suffix属性。 -
DifferentSubtreeTempEntryRenamingStrategy:使用<ldap:different-subtree-renaming-strategy />元素。它将子树 DN 附加到 DN 的最低有效部分。这样做会使所有临时条目都放置在 LDAP 树中的特定位置。临时子树 DN 是通过设置subtree-node属性。例如,如果subtree-node是ou=tempEntries条目的原始 DN 为cn=john doe, ou=users,则临时 DN 为cn=john doe, ou=tempEntries.请注意,配置的子树节点需要存在于 LDAP 树中。
这DefaultTempEntryRenamingStrategy在某些情况下不起作用。例如,如果您计划进行递归删除,则需要使用DifferentSubtreeTempEntryRenamingStrategy.这是因为递归删除作实际上包括对子树中每个节点的深度优先删除。由于您无法重命名具有任何子项和DefaultTempEntryRenamingStrategy将每个节点保留在同一个子树中(具有不同的名称)而不是实际删除它,则此作将失败。如有疑问,请使用DifferentSubtreeTempEntryRenamingStrategy. |