Насколько я знаю, конфигурация отработки отказа зависит от драйвера 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)
)
)
)
, а затем в вашей конфигурации:
spring.datasource.url=jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER
Конечно, вы можете не иметь или не хотите использовать 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))))
См. эти ссылки для получения дополнительной информации о дескрипторах соединения, tnsnames.ora
и настройке аварийного переключения для БД Oracle:
Обратите внимание, что службаимя должно быть одинаковым во всех базах данных, поэтому я заменил db1
и db2
из вашей конфигурации на db
.
Если вы хотите иметь разные имена служб, вы должны настроитьотдельные источники данных программно (как описано Sheetal Mохан Шарма).
Редактировать:
- Полученная ошибка указывает на то, что вы пытаетесь подключиться к имени службы, которая не существует на сервере - подробнее здесь
Сегодня я перечитал документацию (в частности, PDF-файл, на который я ссылался выше) более внимательно, и кажется, что в строке подключения можно указать дополнительное имя службы, так что в вашем случаезапись в tnsnames.ora будет выглядеть следующим образом:
CONNECTION_WITH_FAILOVER = (ОПИСАНИЕ = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = primary.com) (PORT = 1521)) (ADDRESS = (PROTOCOL = TCP) (HOST = second.com) (PORT = 1521)) (LOAD_BALANCE = нет) (FAILOVER = да)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = db1) (FAILOVER_MODE = (TYPE = select) (METHOD = preconnect) (RETRIES = 180) (DELAY = 10) (BACKUP = db2))))
и в виде URL JDBC в 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))))
У меня нет такой настройки в настоящее время, поэтому я положил ее в свой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 = нет) (FAILOVER = yes)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = my-service-name) (FAILOVER_MODE = (TYPE =выберите) (METHOD = preconnect) (RETRIES = 1) (DELAY = 1))))
для имитации основного сбоя соединения (поскольку очевидно, что на google.com не работает Oracle DB)) и мне удалось подключиться к моей базе данных с помощью DataGrip, используя URL-адрес подключения: jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER
Я также попытался выполнить это с дескриптором подключения непосредственно в URL-адресе JDBC:
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))))
, и он также работалхотя оба раза установление соединения занимало довольно много времени (но это может быть связано с конфигурацией моей сети или со значением времени ожидания соединения для драйвера)
- Убедитесь, что вы настроили
FAILOVER_MODE
параметр тдля удовлетворения ваших потребностей - особенно обратите внимание на значения RETIRES и DELAY - в приведенном мною примере я использовал 180 попыток и 10 секундную задержку между попытками, добавив к этому тайм-аут соединения при каждой повторной попытке, и может потребоваться очень много времени, прежде чем драйвер фактическипереключается на аварийное соединение.