В Spring LDAP как повторно использовать одно и то же соединение и BIND для двух операций LdapTemplate? - PullRequest
0 голосов
/ 28 ноября 2018

Вот вопрос:Как я могу гарантировать, что одно и то же LDAP-соединение используется при последующих вызовах LdapTemplate , когда экземпляр LdapTemplate создается с PooledContextSource ?Если бы это было важно, это было бы в рамках одной и той же транзакции.

Вот фон, который привел к вопросу:Я надеялся, что TransactionAwareContextSourceProxy будет повторно использовать одно и то же TCP-соединение (привязку) к серверу LDAP через вызовы LdapTemplate в рамках той же активной транзакции.

При просмотре журналов моего сервера LDAP это, похоже, небыть так.Если я делаю запись, а затем поиск в той же транзакции, я вижу BIND / MODDN / UNBIND / BIND / SEARCH / UNBIND в журналах сервера.Журналы также показывают, что два BIND являются отдельными подключениями от пула.Для меня это никоим образом не работает, потому что нашему кластеру LDAP требуется некоторое время для репликации между узлами (не говоря уже о том, что повторное связывание по операциям просто неэффективно.)

При более внимательном рассмотрении документации TransactionAwareContextSourceProxy, в которой говоритсяthis:

Прокси-сервер для ContextSource, чтобы убедиться, что возвращенные объекты DirContext осведомлены об окружающих транзакциях.Это гарантирует, что DirContext не будет закрыт во время транзакции и что все операции модификации записываются, отслеживая соответствующие операции отката.

Таким образом, кажется, что все, что действительно гарантирует, это то, что соединения не являютсязакрыто до фиксации времени.Вопреки моей надежде, это не гарантирует одно и то же соединение между различными вызовами LdapTemplate для каждой транзакции.

Я не думаю, что пул SingleContextSource объектов также работает, потому что я ожидал, что LdapTemplateпросто извлекает отдельный SingleContextSource из пула для каждой операции в транзакции.

EDIT: Полагаю, я мог бы сделать что-то вроде следующего псевдокода.Я еще не проверял это, и я оставлю это другим, чтобы сказать мне, является ли это лучшим решением или нет.

SingleContextSource singleContextSource = new SingleContextSource(pooledContextSource.getReadWriteContext());
try {
    LdapTemplate ldapTemplate = new LdapTemplate(singleContextSource);
    ldapTemplate.op1();
    ldapTemplate.op2();
}
finally {
    singleContextSource.destroy();
    /* Whatever method needs to be called to return pooledContextSource to pool?  Maybe singleContextSource.destroy() is enough to do that? */
}
...