As far as I know the failover configuration is dependent on the JDBC driver. In case of Oracle you configure it with connect descriptors. So in your case you would put this in 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)
)
)
)
and then in your configuration:
spring.datasource.url=jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER
Of course, you may not have or want to use tnsnames.ora
, in which case you can use connect descriptor as a part of JDBC connection string:
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))))
See these links for more details on connection descriptors, tnsnames.ora
and configuring failover for Oracle DB:
Note that the service name must be the same on all databases, so I replaced db1
and db2
from your configuration with db
.
If you want to have different service names you must configure separate data sources programmatically (as described by Sheetal Mohan Sharma).
Edit:
- The error you got indicates that you are trying to connect to a service name that does not exist on the server - more here
I reread the documentation (specifically the PDF I linked above) more carefully today and it seems that it is possible to specify secondary service name in the connect string, so in your case entry in tnsnames.ora would be:
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)
)
)
)
and as a JDBC URL in application.properties:
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))))
I do not have such setup currently configured, so I put this in my 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)
)
)
)
to simulate primary connection failure (because obviously there is no Oracle DB running on google.com) and managed to connect to my database with DataGrip using connection URL: jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER
I also tried this with connect descriptor directly in the JDBC URL:
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))))
and it worked as well, although both times it took quite some time for the connection to be established (but that may be related to my network configuration or possibly the connection timeout value for the driver)
- Make sure you configure
FAILOVER_MODE
parameter to suit your needs - consider especially the RETIRES and DELAY values -in the example I provided I used 180 retries and 10 second delay between retries, add to that the connection timeout on every retry and it might take a very long time before the driver actually switches to the failover connection.