Блокировка заказа в C3p0 - PullRequest
5 голосов
/ 16 марта 2009

Я пытаюсь зарегистрировать создание и уничтожение соединений с базой данных в нашем приложении, используя c3p0 ConnectionCustomizer. В нем у меня есть код, который выглядит следующим образом:

log(C3P0Registry.getPooledDataSources())

Я захожу в тупик. Я обнаружил, что c3p0 имеет по крайней мере пару объектов в своей библиотеке, которые используют синхронизированные методы, и, похоже, не указывают их предполагаемый порядок блокировки. Когда я регистрирую соединения, я держу блокировку на C3P0Registry и в итоге PoolBackedDataSource (простое создание списка источников данных вызывает хеш-код, вызывающий блокировку).

Завершение работы провайдера соединений (вызов C3P0ConnectionProvider.close()) приводит к вызову блокировок в обратном порядке. Но пока дочерние источники данных закрываются, моя регистрация запускается. Результат - тупик.

Кажется, что оба вызова, которые я делаю в библиотеку c3p0, действительны, ожидаемые вызовы:

  • C3P0ConnectionProvider.close()
  • C3P0Registry.getPooledDataSources()

Также кажется, что (если это явно не указано в документации) библиотека должна нести ответственность за управление своей собственной стратегией блокировки. (Я не говорю это, чтобы обвинять кого-либо ... просто чтобы подтвердить мое понимание лучших практик)

Как мне решить эту проблему? Поскольку c3p0 использует синхронизированные методы, а не более современный механизм, я не могу на самом деле проверить блокировки.

Из моего DataSource кода закрытия я мог бы сначала захватить блокировку C3P0Registry перед закрытием DataSource. Я бы угадал правильный порядок блокировки, который я не знаю, чувствую ли я себя комфортно.

Не думаю, что смогу отменить порядок блокировки для регистрации вызовов. Мне нужен C3P0Registry, чтобы получить список DataSources, поэтому я не мог заблокировать DataSources без первой блокировки C3P0Registry, чтобы получить ссылки на них.

Другое решение, конечно, состоит в том, чтобы обеспечить другую, более высокую блокировку уровня выше всего c3p0. В случае пула соединений это, кажется, лишает смысла точку.

Пока я откатываю свою регистрацию. Спасибо за любую помощь.

1 Ответ

0 голосов
/ 05 февраля 2011

Я не знаю, как решить проблему с блокировкой, но я думаю, что вам следует сделать шаг назад и подумать об исходной проблеме. «Я пытаюсь зарегистрировать создание и уничтожение соединений с базой данных в нашем приложении ...»

Я бы порекомендовал следующее.

Создайте класс и сделайте его реализующим javax.sql.DataSource. Создайте поле того же типа и делегируйте ему все методы. В методе getConnection () верните свой собственный класс Connection java.sql. соединение и так далее. Затем оберните этот класс вокруг вашего исходного источника данных. В ваших классах вы теперь можете просто создать регистратор и записывать все действия, которые вы хотите видеть в своем журнале.

...