Как смоделировать сбой базы данных для проверки двухфазной фиксации в Java

Я выполняю двухэтапную фиксацию с использованием распределенных ресурсов. Как смоделировать отказ участвующей базы данных? Вытягивание сетевого кабеля не работает, так как вызывает тупиковую ситуацию с таблицей. В настоящее время я использую в своем коде приложения хуки, которые бросают StaleConnectionException в разные моменты, например, до выполнения запроса, после выполнения запроса. Меня беспокоит этот подход:

  • Есть ли лучший способ имитировать сбой БД?
  • Что происходит с объектом подключения, когда соединение с БД нарушается? Сохраняет ли он свое значение или становится нулевым?
  • Что на самом деле происходит, когда приложение пытается повторно подключиться к БД? Какое значение получает объект подключения? Использует ли он существующее значение из пула подключений?

Я также хотел бы протестировать в промежуточных точках, например, во время выполнения запроса, во время фиксации (после отправки prepare и т. Д.). Прямо сейчас я перевожу приложение в режим отладки, перехожу к вызову функции и подключаюсь к нему. Но этот подход является ручным и не подходит для масштабного тестирования.

Есть ли симулятор / эмулятор или инструмент, который может помочь мне в этом?


person Andy    schedule 11.04.2012    source источник
comment
Вы ориентируетесь на какую-то конкретную базу данных или это должно быть универсальное решение для любой базы данных, подключенной к JDBC?   -  person kgrittn    schedule 11.04.2012
comment
Я использую DB2 и DB2 z / OS прямо сейчас.   -  person Andy    schedule 11.04.2012
comment
Энди, какой метод моделирования сбоя базы данных ты выбрал?   -  person Dmitry D    schedule 11.09.2013
comment
@dmiandre: это было когда-то назад, так что не помню ... но я думаю, что один из методов, который я сделал, заключался в том, чтобы убедиться, что запрос во 2-й БД выдал ошибку (неправильное имя таблицы или что-то в этом роде). Таким образом, второй запрос не прошел в то время как 1-й достигает фазы фиксации. Моей основной целью было провалить двухэтапную фиксацию, чтобы это сработало! Попробую откопать старый проект и посмотреть, смогу ли я найти какие-либо другие используемые методы.   -  person Andy    schedule 11.09.2013
comment
Я искал в Интернете лучшие практики для проверки таких случаев, но, похоже, никто не проверял это. Единственное, что я нашел, это Byteman от JBoss. Это инструмент для внедрения ошибок без изменения вашего кода.   -  person Dmitry D    schedule 11.09.2013


Ответы (4)


Это много вопросов :) Постараюсь дополнить предыдущие ответы.

Is there a better way to simulate the DB failure?

Проверка всех случаев сложна. Один из способов проверить основные случаи - создать соединитель JCA (драйвер БД является соединителем JCA). Вы можете получить подключения от коннектора, который будет включен в транзакцию (третий участник). В этом случае соединение может вызвать определенные ошибки.

Есть три части, которые работают вместе: (1) приложение, (2) приложение. диспетчер транзакций сервера и (3) соединитель jca (так называемый адаптер ресурсов).

Связь между тремя частями

Соединение подключается к транзакции через 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
comment
Спасибо за такое подробное объяснение. У меня еще нет времени проверить это. Я проголосую за, как только смогу его протестировать, но все же спасибо за такое подробное объяснение - person Andy; 07.05.2012
comment
Надеюсь, это поможет. То, что вы хотите сделать, непросто. (И, как писал @ nsfyn55, существует чрезвычайно высокая стоимость / низкое вознаграждение) - person ewernli; 08.05.2012

Вероятно, вы можете добавить свой собственный ресурс, который будет участвовать в фиксации и приостанавливать транзакцию после первой фазы. А пока можно «вытащить вилку».

person Andrej    schedule 11.04.2012
comment
Я не могу добавить больше ресурсов, чем у меня уже есть. Кроме того, я не контролирую их работу, я не могу останавливать и запускать их, поскольку они являются базами данных разработчиков. - person Andy; 11.04.2012
comment
Я думаю, что Андрей имел в виду подключить еще один (фиктивный) XAResource, который вызовет какой-то сбой между подготовкой и фиксацией. Правильный способ - создать адаптер ресурсов. Вы также можете попробовать подключить XAResource непосредственно из вашего приложения, но я думаю, что WebSphere не позволяет этого через стандартные JTA API (обратите внимание, что обычно это не разрешено J2EE в любом случае). Вам нужно будет использовать API, специфичный для WebSphere (поскольку WebSphere требует, чтобы вы сгенерировали так называемый токен восстановления при включении XAResource). - person Andreas Veithen; 11.04.2012

Андрей ответил на одну часть вопроса, поэтому позвольте мне ответить на вторую часть.

Объект Connection, который вы получаете в своем приложении, является лишь оболочкой физического соединения. Эта оболочка играет роль в создании пула соединений и управлении транзакциями. Если что-то пойдет не так с БД, оболочка соединения станет непригодной для использования, и вы сможете только выполнить откат. Это имеет смысл, потому что вы получаете доступ к соединению только до запуска 2PC, и все, что было сделано до запуска 2PC, невозможно восстановить.

Обратите внимание, что попытка разорвать соединение и получить новое ничего не меняет, потому что после того, как соединение из заданного источника данных было использовано в транзакции, вы всегда будете получать такое же соединение из этого источника данных, пока вы находитесь в та же сделка. Это означает, что ваше приложение не может «повторно подключиться» без перезапуска всей транзакции.

С другой стороны, если что-то пойдет не так после того, как все ресурсы будут подготовлены, но до того, как все ресурсы будут зафиксированы, то ответственность за восстановление транзакции лежит на диспетчере транзакций. Но это происходит негласно, и ваше приложение не контролирует ситуацию. Также на этом этапе ожидается, что ваше приложение освободит все соединения, используемые в этой транзакции.

person Andreas Veithen    schedule 11.04.2012
comment
Спасибо за подробное объяснение. В моем случае происходит следующее: я выполняю запрос к обеим БД как часть транзакции, и, когда она собирается зафиксироваться, я отключаю. Приложение выдает исключение javax.transaction.HeuristicMixedException, а затем пытается выполнить откат. Теперь, когда TM (в моем случае Websphere) пытается выполнить откат, он получает следующее исключение: Произошло исключение XAException. Код ошибки: XAER_NOTA (-4) ERRORCODE = -4228, SQLSTATE = null. Тогда мой вопрос: если фиксация никогда не вызывалась, подготовка никогда не отправлялась. Должен ли TM по-прежнему вызывать откат? - person Andy; 12.04.2012
comment
Кроме того, достаточно ли моего подхода jst к выбросу StaleConnectionException для имитации сбоя БД, или я должен также освободить соединения? - person Andy; 12.04.2012

Лучше всего, вероятно, использовать в базах данных памяти. Вызовите сбой и проверьте состояние источников данных до и после, чтобы убедиться, что откат / фиксация выполнены правильно.

Что касается других ваших проблем, это похоже на тесты с чрезвычайно высокой стоимостью / низким вознаграждением. Прочтите документацию поставщиков и убедитесь, что ваша транзакционная среда настроена должным образом. После того, как это будет сделано, вам, вероятно, следует автоматизировать его, чтобы не было никаких проблем.

Если вы не написали свой собственный менеджер транзакций для протокола 2PC + реализацию БД, я бы оставил тестирование этих функций вашему поставщику.

person nsfyn55    schedule 11.04.2012