Обзор:
Мне интересно узнать, что лучше всего подходит для приложений с высокой пропускной способностью, которые имеют массовые сообщения, пытающиеся обновить одну и ту же строку и получающие ошибки взаимоблокировки оракула. Я знаю, что вы не можете избежать этих ошибок, но как вы восстанавливаетесь после них изящно, не увязая в таких ошибках взаимоблокировки, возникающих снова и снова.
Подробности:
Мы создаем приложение для обмена сообщениями JMS с высокой пропускной способностью. Производственная среда будет состоять из двух узлов weblogic 11g (на каждом из которых запущено 6 экземпляров прослушивателя MDB). Мы получали ошибки взаимоблокировки Oracle (ORA-00060), когда мы получали около 1000 сообщений, пытающихся обновить одну и ту же строку в базе данных оракула. Синхронизация Java между узлами невозможна в стандартном API потоковой передачи Java (если нет другого решения, мы не хотим использовать какие-либо сторонние решения, такие как терракота и т. д.).
Мы надеялись, что оператор Oracle «выбрать для обновления WAIT n secs» поможет, потому что это, по сути, заставит конкурирующие потоки (для одной и той же строки) ждать несколько секунд, прежде чем первый поток (который первым получил блокировку строки) закончит с этим. .
Первая проблема с «SELECT FOR UPDATE WAIT n» заключается в том, что он не позволяет использовать миллисекунды для времени ожидания. Это начинает отрицательно сказываться на пропускной способности нашего приложения, потому что установка 1 секунды WAIT (наименьшее время ожидания) вызывает задержки сообщений.
Во-вторых, мы возимся с параметром задержки повторной доставки очереди weblogic (30 секунд в нашем случае). Всякий раз, когда поток возвращается из-за ошибки взаимоблокировки, он будет ждать 30 секунд перед повторной попыткой.
По нашему опыту, 1000 конкурирующих сообщений во многих ситуациях обрабатываются целую вечность, потому что взаимоблокировка повторяется снова и снова.
Я понимаю, что с текущей архитектурой мы должны получать ошибки взаимоблокировки независимо (в случае 1000 конкурирующих сообщений), но приложение должно быть достаточно устойчивым, чтобы восстанавливаться после этих ошибок после повторной попытки зацикливания сообщений.
Есть идеи, что нам здесь не хватает? кто-нибудь уже имел дело с подобными проблемами?
Я ищу некоторые дизайнерские идеи, которые могут сделать эту работу отказоустойчивой, чтобы она восстанавливалась из этой тупиковой ситуации и в конечном итоге обрабатывала все сообщения в разумные сроки без использования большого количества дополнительного оборудования.
ДЕТАЛИ РАСЧЕТА: КАЖДОЕ из этих 1000 сообщений создаст 4 объекта 4 разных типов позиций, с каждым из которых связано количество. Эти количества должны быть объединены в эти 4 разных слота (в зависимости от типа позиции). Тупик возникает, когда эти 4 отдельных слота обновляются каждым отдельным потоком. Мы уже заказали эти отдельные обновления в определенном порядке, прежде чем применять их к строкам базы данных, чтобы избежать любых возможных условий гонки.