Spring引导JDBCTemplate与c3p0 DataBase池和故障转移

sun*_*leo 6 java jdbc spring-jdbc c3p0 spring-boot

我需要在SpringBoot应用程序(嵌入式tomcat)中使用jdbctemplate建立数据库连接失败,使用c3p0连接池.这是我的应用程序的应用程序.我有主数据库和辅助数据库.如果主要失败则应使用辅助数据库运行时的数据库连接故障转移.请帮助我实现这一点.我试图包含多个数据库URL作为配置的一部分,但是无法正常工作.

c3p0 Java数据库池,故障转移配置 https://docs.genesys.com/Documentation/Composer/8.1.4/Help/ConnectionPooling

application.properties :(错误即将到来)

#      connection properties for data source
##########################################################################################################
spring.datasource.c3p0.driverClass=oracle.jdbc.driver.OracleDriver
spring.datasource.c3p0.maxConnectionAge=3600
spring.datasource.c3p0.maxIdleTime=600
spring.datasource.c3p0.initialPoolSize=5
spring.datasource.c3p0.maxPoolSize=10
spring.datasource.c3p0.minPoolSize=5
spring.datasource.c3p0.acquireIncrement=1

##########################################################################################################


spring.datasource.url=jdbc:oracle:thin:@primary.com:1521:db1,jdbc:oracle:thin:@secondary.com:1521:db2
spring.datasource.username=user
spring.datasource.password=password
Run Code Online (Sandbox Code Playgroud)

Kon*_*tor 6

据我所知,故障转移配置依赖于JDBC驱动程序.对于Oracle,您可以使用连接描述符对其进行配置.所以在你的情况下,你会把它放在tnsnames.ora:

CONNECTION_WITH_FAILOVER = 
    (DESCRIPTION =
        (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = primary.com)(PORT = 1521))
            (ADDRESS = (PROTOCOL = TCP)(HOST = secondary.com)(PORT = 1521))
            (LOAD_BALANCE = no)
            (FAILOVER = yes)
        )
        (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = db)
            (FAILOVER_MODE =
                (TYPE = select)
                (METHOD = preconnect)
                (RETRIES = 180)
                (DELAY = 10)
            )
        )
    )
Run Code Online (Sandbox Code Playgroud)

然后在你的配置中:

spring.datasource.url=jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER 
Run Code Online (Sandbox Code Playgroud)

当然,您可能没有或想要使用tnsnames.ora,在这种情况下,您可以使用连接描述符作为JDBC连接字符串的一部分:

spring.datasource.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=primary.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=secondary.com)(PORT=1521))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=180)(DELAY=10))))
Run Code Online (Sandbox Code Playgroud)

有关连接描述符tnsnames.ora和为Oracle DB配置故障转移的更多详细信息,请参阅以下链接:

请注意,服务名称必须对所有数据库一样的,所以我代替db1db2从您的配置db.

如果要使用不同的服务名称,则必须以编程方式配置单独的数据源(如Sheetal Mohan Sharma所述).

编辑:

  • 您收到的错误表明您正在尝试连接服务器上不存在的服务名称 - 此处更多
  • 我今天更仔细地重读了文档(特别是我上面链接的PDF),似乎可以在连接字符串中指定辅助服务名称,因此在您的情况下,tnsnames.ora中的条目将是:

    CONNECTION_WITH_FAILOVER =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = primary.com)(PORT = 1521))(ADDRESS =(PROTOCOL = TCP)(HOST = secondary.com)(PORT = 1521)) (LOAD_BALANCE = no)(FAILOVER = yes))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = db1)(FAILOVER_MODE =(TYPE = select)(METHOD = preconnect)(RETRIES = 180)(DELAY = 10)(BACKUP = db2))))

并作为application.properties中的JDBC URL:

spring.datasource.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=primary.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=secondary.com)(PORT=1521))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db1)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=180)(DELAY=10)(BACKUP = db2))))
Run Code Online (Sandbox Code Playgroud)
  • 我目前没有配置这样的设置,所以我把它放在我的tnsnames.ora中:

    CONNECTION_WITH_FAILOVER =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = google.com)(PORT = 1521))(ADDRESS =(PROTOCOL = TCP)(HOST = my-actual-database)(PORT = my -db-port))(LOAD_BALANCE = no)(FAILOVER = yes))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = my-service-name)(FAILOVER_MODE =(TYPE = select)(METHOD = preconnect)(RETRIES = 1)(DELAY = 1))))

模拟主连接失败(因为很明显,google.com上没有运行Oracle数据库)并设法使用连接URL连接到DataGrip数据库: jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER

我也直接在JDBC URL中尝试使用connect descriptor:

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=google.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=my-actual-database)(PORT=my-db-port))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=my-service-name)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=1)(DELAY=5))))
Run Code Online (Sandbox Code Playgroud)

虽然两次都需要花费相当长的时间来建立连接(但这可能与我的网络配置或驱动程序的连接超时值有关)

  • 确保配置FAILOVER_MODE参数以满足您的需求 - 特别考虑RETIRES和DELAY值 - 在我提供的示例中,我使用180次重试和重试之间的10秒延迟,在每次重试时添加连接超时并且可能需要很长时间驱动程序实际切换到故障转移连接之前的时间.