參考 官網 transaction 的設定
Transaction Settings
xml:
<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>
這裡的 ldap:default-renaming-strategy
其實就是 DefaultTempEntryRenamingStrategy
這隻 class。
LDAP Operation | Recording | Preparation | Commit | Rollback |
---|---|---|---|---|
bind | Make record of the DN of the entry to bind. | Bind the entry. | No operation. | Unbind the entry using the recorded DN. |
unbind | Make record of the original DN and calculate a temporary DN. | Rename the entry to the temporary location. | Unbind the temporary entry. | Rename the entry from the temporary location back to its original DN. |
遇到的問題:
之前遇到的情況是當我 unbind
DN 時,我發現我要刪除的 DN (假設為 ou=test
)變成 ou=test_temp
。
結果就發現上面這個表格,當使用 unbind
這個操作時,DefaultTempEntryRenamingStrategy
會先幫我加上 _temp
,
如果最後這個 transaction 是 commit
的話,就會正常刪除。但是如果有 Exception
的話,有可能會看到 ou=test_temp
這個出現在 Ldap Server 中。
理由:
因為我們使用的 transaction manager
是 ContextSourceTransactionManager
這隻 class,而這隻 extends
AbstractPlatformTransactionManager
。
我們可以看到在 AbstractPlatformTransactionManager
裡面的 rollbackOnCommitFailure
是設定 false
public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
...
private boolean rollbackOnCommitFailure = false;
...
}
所以當我們存取 Ldap Server 有遇到錯誤時,預設是沒有 rollback
的,然後 transactionManager
還來不及 commit
就把 Exception
丟出來,導致我們看到 ou=test_temp
。
解決方式:
將 ContextSourceTransactionManager
的 rollbackOnCommitFailure
設為 true
。
java:
@Configuration
public class MyConfiguration {
@Bean
public ContextSourceTransactionManager contextSourceTransactionManager(ContextSource contextSource) {
ContextSourceTransactionManager contextSourceTransactionManager =
new ContextSourceTransactionManager();
contextSourceTransactionManager.setContextSource(contextSource);
contextSourceTransactionManager.setRenamingStrategy(new DefaultTempEntryRenamingStrategy());
contextSourceTransactionManager.setRollbackOnCommitFailure(true);
return contextSourceTransactionManager;
}
}
目前是用這種方式解決。
感谢分享