Состояние гонки на MDB: какой лучший способ справиться с этим? - PullRequest
2 голосов
/ 20 января 2012

У меня есть приложение на основе событий, основанное на MDB, пружинной интеграции и JPA для сохранения. Приложение развернуто в Weblogic 10.3 со значением по умолчанию максимального размера пула (16).

Мое приложение должно обрабатывать некоторые сообщения, которые модифицируют БД. Представьте себе, что у меня есть сценарий использования, когда мне приходится обрабатывать некоторые сообщения, для которых по их логике необходимо вставить объект домена, если он не существует, или обновить его, если он существует.

Итак, мой компонент, который модифицирует БД, проверяет, существует ли объект или нет, а затем вызывает слияние для JPA. Поскольку два параллельных сообщения выполняются параллельно, когда я вызываю слияние на dao, JPA запускает два оператора вставки, поскольку объект еще не сохранен, и поэтому правильно выполняется только одно из них.

Существует ли шаблон для обработки такого рода "состояния гонки" в приложении, управляемом событиями?

С уважением Massimo

1 Ответ

1 голос
/ 20 января 2012

Самое простое решение - перехватить исключение, выданное второй вставкой, а затем снова вызвать merge, что должно выполнить обновление.

В качестве альтернативы вы можете попробовать выполнить изоляцию транзакции merge в SERIALIZABLE, которая должна гарантировать, что вторая merge заблокирована до завершения первой, а вторая - выполнить обновление.

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

...