[Java] Spring Ldap Transaction

參考 官網 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 managerContextSourceTransactionManager 這隻 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

解決方式:

ContextSourceTransactionManagerrollbackOnCommitFailure 設為 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;
  }
}

目前是用這種方式解決。

Reference

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s