|
该版本仍在开发中,尚未被视为稳定。对于最新稳定版本,请使用 Spring LDAP 4.0.0! |
交易支持
习惯使用关系型数据库的程序员进入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 />
...
虽然这种配置在大多数简单场景下运行良好,但一些更复杂的场景需要额外配置。
具体来说,如果你需要在事务中创建或删除子树,你需要使用替代方案临时条目重命名策略,如《重命名策略》中所述。 |
在现实中,你可能会把事务应用到服务对象层面,而不是仓库层面。前面的例子说明了这一大致的思路。
JDBC事务集成
在与 LDAP 对抗时,一个常见的用例是部分数据存储在 LDAP 树中,而其他数据存储在关系数据库中。在这种情况下,事务支持变得更加重要,因为不同资源的更新需要同步。
虽然不支持实际的 XA 事务,但通过提供数据来源参考归属于<ldap:transaction-manager>元素。这会生成一个ContextSourceAndDataSourceTransactionManager然后,这两笔交易几乎像一笔一样管理。执行提交时,始终优先执行 LDAP 部分作,若提交失败,则可回滚两个事务。JDBC部分的交易管理方式完全如下:DataSourceTransactionManager,但不支持嵌套事务。以下示例展示了一个LDAP:事务管理器元素数据来源参考属性:
<ldap:transaction-manager data-source-ref="dataSource" >
<ldap:default-renaming-strategy />
<ldap:transaction-manager />
| 所提供的支持完全是客户端的。 包裹交易不是XA事务。不执行两阶段提交,因为 LDAP 服务器无法对其结果进行投票。 |
你可以通过提供会话工厂参考归属于<ldap:transaction-manager>元素如下:
<ldap:transaction-manager session-factory-ref="dataSource" >
<ldap:default-renaming-strategy />
<ldap:transaction-manager />
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 中最不重要的部分加一个后缀。例如,对于 的 DNcn=约翰·多,ou=用户该策略返回一个临时DNcn=约翰·doe_temp,ou=用户.你可以通过设置临时后缀属性。 -
不同的子树TempEntryRenamingStrategy:通过使用<ldap:different-subtree-renameing-strategy />元素。它会将子树 DN 附加到最低有效部分。这样做使所有临时条目都被放置在 LDAP 树中的特定位置。临时子树DN的配置是通过设置子树节点属性。例如,如果子树节点是ou=temp条目而该条目的原始DN为cn=约翰·多,ou=用户,临时DN为cn=约翰·多,ou=tempEntries.注意,配置后的子树节点必须存在于LDAP树中。
这DefaultTempEntryRenameingStrategy在某些情况下,这并不起作用。例如,如果你计划进行递归删除,你需要使用不同的子树TempEntryRenamingStrategy.这是因为递归删除作实际上是对子树中每个节点分别进行深度优先删除。因为你不能重命名包含任何子项和DefaultTempEntryRenameingStrategy如果会让每个节点都留在同一个子树(但名称不同),而不是实际移除,这个作会失败。有疑问时,就用不同的子树TempEntryRenamingStrategy. |