Spring Boot:如何通过spring.datasource中的外部配置属性设置Oracle Production数据库连接的重试尝试

时间:2016-09-20 06:54:34

标签: oracle11g spring-boot spring-jdbc

我是Spring的新用户,我希望为retry attempts设置Oracle与我们的Spring Boot Java Application相关联。我在application.yml文件中指定了很少spring.datasource个属性。

数据源:

driverClassName: oracle.jdbc.driver.OracleDriver
url: "jdbc:oracle:thin:@//xxx-xxx-x-xxx:1521/database"
username: scott
password: tiger

我已经提到了这个link,它提供了一个常见的Spring Boot属性列表,但我找不到设置spring boot data-source重试次数的属性。连接失败时,spring boot会自动重试吗?设置数据源的重试次数是否有意义?

我经常遇到connection reset错误,因此我计划添加重试尝试确保尝试重试连接失败。这是堆栈跟踪:

java.sql.SQLRecoverableException: IO Error: Connection reset
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:682) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:715) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
        at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:385) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:30) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:564) ~[ojdbc7-12.1.0.1.jar!/:12.1.0.1.0]
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:307) ~[tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:200) ~[tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:708) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:642) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:464) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:141) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:115) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:102) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:126) [tomcat-jdbc-8.0.33.jar!/:na]
        at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:279) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:124) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) [hibernate-entitymanager-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) [hibernate-entitymanager-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) [hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) [hibernate-entitymanager-4.3.11.Final.jar!/:4.3.11.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) [spring-orm-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) [spring-orm-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:319) [spring-orm-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054) [spring-context-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829) [spring-context-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) [spring-context-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.5.RELEASE.jar!/:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar!/:1.3.5.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.5.RELEASE.jar!/:1.3.5.RELEASE]
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) [spring-boot-1.3.5.RELEASE.jar!/:1.3.5.RELEASE]  

2 个答案:

答案 0 :(得分:1)

我们建议使用长格式连接网址而不是简易连接。 您可以传递连接描述符,例如RETRY_COUNT和RETRY_DELAY。示例连接URL如下所示。

JDBC:预言:瘦:@ (DESCRIPTION =   (CONNECT_TIMEOUT = 15)(RETRY_COUNT = 20)(RETRY_DELAY = 3)        (ADDRESS_LIST =            (LOAD_BALANCE = ON)                (ADDRESS =(PROTOCOL = TCP)(HOST = primaryscan)(PORT = 1521)))   (CONNECT_DATA =(SERVICE_NAME = myorcldbservicename)))

CONNECT_TIMEOUT:启用时,此参数指示Oracle Net服务等待指定的秒数(示例中为15秒)以完成连接建立。这相当于SQLNET.OUTBOUND_CONNECT_TIMEOUT,它指定客户端建立与oracle数据库实例的连接的时间。 CONNECT_TIMEOUT会覆盖SQLNET.OUTBOUND_CONNECT_TIMEOUT。

RETRY_COUNT:它指定在向客户端返回失败消息之前的网络连接重试次数。在上面的示例中,Oracle Net在向客户端返回错误消息之前重试了3次。这有助于增加获得连接的可能性,从而提高性能。

RETRY_DELAY:此参数指定重新连接尝试之间的等待时间(以秒为单位)。它与RETRY_COUNT结合使用。因此,建议一起使用RETRY_DELAY和RETRY_COUNT以避免不必要的CPU周期。

答案 1 :(得分:0)

这是连接池的一项功能。如果您没有意见,we do have one

您可能正在使用Tomcat数据源,因此请检查its documentation

我不认为重试是解决问题的方法。您可能有一个无效的连接,并且池在为您返回之前未验证它。 Spring Boot 1.4默认情况下会这样做。如果您使用的是1.3,this answer会提供一些其他信息。