Как объединить соединения Oracle в Tomcat?

Мне неясно, как правильно настроить подключение к базе данных Oracle RAC в Tomcat через context.xml. ЭТОТ метод работает для меня:

<Resource
     name="jdbc/mydb"
     auth="Container"
     type="javax.sql.DataSource"
     driverClassName="oracle.jdbc.OracleDriver"
     url="jdbc:oracle:thin:<connection details>"
     username="<username>"
     password="<account>"
     maxTotal="150"
     maxIdle="10"
     />

Но использует ли это пул соединений? Я попытался добавить factory="org.apache.tomcat.jdbc.pool.DataSourceFactory", как было предложено на https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html, и загадочным образом с этим одним изменением я начал получать:

java.sql.SQLException: ORA-01017: invalid username/password; logon denied

Если вместо этого я попробую type="oracle.jdbc.pool.OracleDataSource" и factory="oracle.jdbc.pool.OracleDataSourceFactory", я получу:

Error: Unable to obtain a JDBC connection from Datasource:
java.lang.Exception: Error: Unable to obtain a JDBC connection from Datasource:

Я просмотрел все, но мне не ясно, что для этого лучше всего. Идеи?


person John Fisher    schedule 29.07.2020    source источник
comment
Да, похоже, что ваш первый метод, который работает, должен использовать пул соединений.   -  person pmdba    schedule 29.07.2020
comment
Вы имеете в виду, что пул встроен в драйвер Oracle или в Tomcat? Без прямой ссылки на фабрики пулов?   -  person John Fisher    schedule 29.07.2020
comment
Tomcat имеет пул соединений по умолчанию с именем DBCP 2 — по крайней мере, в версиях Tomcat 8 и 9. См. здесь. Я использовал его так же, как ваш первый (рабочий) пример - ваша конфигурация Resource. В моем случае это было для MySQL. Я никогда не использовал этот параметр factory.   -  person andrewjames    schedule 29.07.2020
comment
Просто добавлю: существует множество альтернатив стандартному пулу Tomcat. Я также использовал Hikari, но в этом случае он был настроен в коде Java веб-приложения, а не через запись ресурса.   -  person andrewjames    schedule 29.07.2020
comment
Я предполагаю, что это меня смущает, потому что в ссылке на документацию Tomcat по пулам JDBC говорится, что требуется фабрика, и значение должно быть org.apache.tomcat.jdbc.pool.DataSourceFactory   -  person John Fisher    schedule 29.07.2020
comment
Я присмотрелся к этому поближе, потому что — да — это сбивает с толку. В новой установке Tomcat 9 я использовал 2 варианта Resource: (1) используя только type="javax.sql.DataSource" и (2) используя factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" с type="org.apache.tomcat.jdbc.pool.DataSource". В обоих случаях я использовал initialSize="4". С настройкой (1) я создал слишком много соединений. С настройкой (2) я получил 4, которых ожидал. Итак, у меня сработали обе настройки, но (а) не использовала объединенные соединения, как ожидалось, тогда как (б) использовала. Мой комментарий выше кажется неверным.   -  person andrewjames    schedule 29.07.2020
comment
Хорошо, ваши настройки, похоже, сработали для меня, Эндрю... спасибо!   -  person John Fisher    schedule 30.07.2020


Ответы (2)


универсальный пул соединений (UCP) — это пул соединений Java, который вы также можете использовать. Он многофункциональный и хорошо работает с Oracle RAC, DG и т. д. Ознакомьтесь с UCPServlet для примера.

person Nirmala    schedule 30.07.2020

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

Сводка

Оба следующих подхода будут использовать пулы соединений с БД:

  • Используйте более новый пул DBCP 2 по умолчанию Tomcat с type="javax.sql.DataSource".
  • Используйте старый пул JDBC Tomcat с factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" и type="org.apache.tomcat.jdbc.pool.DataSource".

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

Пул DBCP 2 Tomcat по умолчанию

Чтобы использовать пул соединений Tomcat DB по умолчанию через ресурс JNDI, вы должны следовать инструкциям, приведенным на этой странице документации Tomcat: Инструкции по источнику данных JNDI

В частности, вам нужно использовать type="javax.sql.DataSource".

Вот очень простая конфигурация ресурса — не подходит для производства, но полезна для иллюстрации подхода. И это для MySQL, а не для Oracle, поэтому потребуются некоторые настройки:

<Resource name="jdbc/my_db" 
          auth="Container" 
          type="javax.sql.DataSource"
          initialSize="5"
          username="db_user"
          password="***"
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mytestdb" />

При использовании initialSize="5" я увидел 5 ожидаемых соединений на сервере БД.

В JVM был создан пул соединений — как показано в этом дампе кучи VisualVM:

введите здесь описание изображения

Здесь мы видим, что пул создан, у него 5 объектов соединения, и он использует Tomcat DBCP, который, в свою очередь, является ответвлением Apache Commons DBCP 2.

DBCP 2 обеспечивает поддержку JDBC 4.1.

Доморощенный пул JDBC от Tomcat

Если вы посмотрите на документацию Tomcat на этой другой странице - Соединение Tomcat JDBC Пул — вы увидите другое руководство.

В частности, в нем говорится, что вам нужны оба следующих элемента в вашем <Resource>:

factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
type="org.apache.tomcat.jdbc.pool.DataSource"

Если вы используете это, вы также будете использовать пул соединений БД, но он будет основан на более старом пакете пула Tomcat JDBC:

введите здесь описание изображения

В этом примере я использовал initialSize="3".

В документации Tomcat это представлено как новый пул соединений (он был заменой ранее использовавшемуся Commons DBCP 1.x). Оно не такое новое, как решение Tomcat по умолчанию DBCP 2. Я думаю, что формулировка документации уже устарела. И несколько запутанно из-за этого.

Дополнительные примечания

Примечания от члена команды по фиксации Tomcat (см. здесь ):

Tomcat JDBC — это собственный пул подключений к базе данных Tomcat, не использующий poolPreparedStatements

Tomcat DBCP — это пакет Tomcat, переименованный в ответвление Apache Commons DBCP 2.

Tomcat DBCP используется по умолчанию.

Вы всегда можете реализовать пул непосредственно в коде, не используя аннотацию JNDI <Resource>. Есть много доступных вариантов.

(В моих первоначальных тестах была проблема с моей установкой Tomcat, которая привела к созданию слишком большого количества соединений для DBCP 2. Сначала это ввело меня в заблуждение).

person andrewjames    schedule 31.07.2020