Это много вопросов :) Постараюсь дополнить предыдущие ответы.
Is there a better way to simulate the DB failure?
Проверка всех случаев сложна. Один из способов проверить основные случаи - создать соединитель JCA (драйвер БД является соединителем JCA). Вы можете получить подключения от коннектора, который будет включен в транзакцию (третий участник). В этом случае соединение может вызвать определенные ошибки.
Есть три части, которые работают вместе: (1) приложение, (2) приложение. диспетчер транзакций сервера и (3) соединитель jca (так называемый адаптер ресурсов).
![Связь между тремя частями](https://i.stack.imgur.com/H9VN5.png)
Соединение подключается к транзакции через ManagedConnection.getXAResource
. С помощью настраиваемого коннектора jca вы можете затем вызвать исключение для приложения (Connection
на рисунке) или диспетчера транзакций сервера приложений (XAResource
получено с помощью ManagedConnection
на рисунке). В частности, вы можете генерировать исключение во время XAResource.prepare
и XAResource.commit
, что соответствует ошибкам во время 2-фазной фиксации.
Обратите внимание, что трудно контролировать порядок привлечения участников (см. этот вопрос). Так что легко проверить, что один из prepare
не работает (а именно ваш), но трудно контролировать порядок, в котором они вызываются. Воспроизведение всех возможных недопустимых состояний 2-фазной фиксации затруднено, особенно при использовании оптимизации.
(Однажды я написал коннектор JCA (http://code.google.com/p/txfs) и есть другие, если вам нужен образец кода.)
What happens to the connection object when DB connection goes bad?
Does it retain its value or does it become null?
ManagedConnection
может уведомлять диспетчер транзакций. Одно из уведомлений - ConnectionEvent.CONNECTION_ERROR_OCCURRED
, информирующее о том, что при использовании этого конкретного соединения произошла ошибка.
Как отмечено в другом ответе, обычно с каждой транзакцией связано одно управляемое соединение. Управляемое соединение абстрагирует физическое соединение, и вы не хотите использовать слишком много. Приложение получает только «ручки» (Connection
на картинке). Все дескрипторы, полученные в рамках одной данной транзакции, указывают на одно и то же управляемое соединение. Это оптимизация, которую поддерживает большинство серверов приложений.
Если управляемое соединение становится недействительным, дескрипторы, которые его используют, также становятся недействительными. Но ручки AFAIK не могут быть "обновлены". Транзакция должна откатиться, управляемое соединение разрушено. Когда начинается другая транзакция, она будет связана с другим допустимым управляемым соединением из пула.
What actually happens when application tries to reconnect to DB?
What value does connection object get?
Does it use an existing value from the connection pool?
Сервер приложений управляет пулом управляемых подключений. Как сказано в предыдущем абзаце, во время использования он может испортиться. Но можно испортиться и без использования. Например, используемое управляемое соединение в пуле может стать недействительным, поскольку истекло время ожидания базового физического соединения. На серверах приложений обычно есть возможность проверить, действительно ли управляемое соединение, прежде чем оно начнет его использовать. В противном случае он попробует другое управляемое соединение из пула или создаст новое.
person
ewernli
schedule
26.04.2012