Spring MVC обновляет компоненты базы данных в контексте приложения
Я разрабатываю веб-приложение Spring MVC, использующее пул соединений с базой данных dbcp.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
</bean>
Недавно я переместил область действия этих компонентов в синглтон, потому что количество подключений за сеанс стало слишком большим.
Проблема в:
Наша база данных закрывается каждое воскресенье, и приложение Spring, кажется, работает странно, оставляя сокет открытым, и не обновляет соединение, как я и думал.
Есть ли способ обновить бины, заданные как синглтон, таким образом, чтобы обновлять соединение каждый день и не было бы необходимости перезапускать приложение каждый понедельник?
1 ответ
Что вы хотите сделать, это настроить проверку для ваших подключений. Когда соединение заимствовано из пула, вы хотите убедиться, что это соединение действительно. Для этого вы можете указать validationQuery
собственности на ваш источник данных.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
<property name="validationQuery" value="select 1 from dual" />
</bean>
См. DBCP - validationQuery для разных баз данных, где приведен список возможных проверочных запросов для разных баз данных.
Есть некоторые проблемы с Commons DBCP, и он довольно старый (хотя есть DBCP 2.x сейчас). Я бы предложил перейти к другому источнику данных, такому как HikariCP. Этот источник данных также является источником данных на основе JDBC 4.x, что позволяет упростить проверку соединения (он является частью спецификации JDBC 4).
<bean id="datasourceAR_XXX" class="com.zaxxer.hikari.HikariDataSource">
<property name="datasourceClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="maximumPoolSize" value="20" />
<property name="username" value="XXX" />
<property name="password" value="XXX" />
<property name="datasourceProperties">
<props>
<prop key="serverName">XXX.XXX.com</prop>
<prop key="port">1500</prop>
<prop key="databaseName">SERVICE</prop>
</props>
</property>
</bean>
Если ваш драйвер оракула достаточно новый, вам больше не нужен запрос проверки, так как проверка выполняется драйвером вместо того, чтобы выполнять запрос. Кроме того, у вас, вероятно, будут лучшие результаты с этим пулом.
Также у вас может быть небольшой размер пула. Хорошую статью / презентацию о размере пула можно найти здесь.