Проблема синхронизации с JMS и JPA - PullRequest
1 голос
/ 06 сентября 2011

У меня есть ситуация, когда мне нужно получить части большого файла через JMS (сгруппированные сообщения) и сохранить его в БД.

Проблема в том, что каждое сообщение в группе будет одной строкой в ​​TABLE A, и существует @ManytoOne связь с TABLE B. Это означает, что для одной группы будет только одна запись в таблице B, но много записей в таблице A.

Моя текущая логика такова, что перед вставкой в ​​table A я проверяю любые записи (@NamedQuery, так как первичный ключ НЕ был бы известен MDB в то время), и если не найден, создание нового (создание первичного ключа Table B здесь).

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

Чтобы быть более понятным:

Шаг 1: Получение сообщения.

Шаг 2. Создайте права доступа, требуемые для ТАБЛИЦЫ А. Проверьте, есть ли какие-либо записи с одинаковым идентификатором группы в таблице B (READ), если они найдены, установите связь и сохраните, если нет, создайте новую сущность для таблицы. B (WRITE) (с созданным первичным ключом сервисом) установить отношение и сохранить его.

Проблема в том, что несколько экземпляров MDB создают запись для таблицы B, поскольку она не может найти запись (созданную первым MDB) во время READ, следовательно, WRITING новые записи для того же идентификатора группы.

Есть ли способ, которым я могу преодолеть эту проблему? 1. Я использую eclipselink и Oracle, управляющие транзакциями контейнеров и менеджеры сущностей внедряются с помощью аннотации @PersistenceContext.

Спасибо

1 Ответ

1 голос
/ 06 сентября 2011

Не совсем уверен, что ты делаешь? Вы пытаетесь не дать обеим транзакциям создать новую A или только новую B?

Вы можете добавить уникальное ограничение на внешний ключ A в таблице B. Это гарантирует, что вторая попытка вставить B для A потерпит неудачу.

Другое решение состоит в том, чтобы использовать для транзакции пессимистическую блокировку на A, это гарантирует, что транзакция не конфликтует.

Вы также можете использовать оптимистическую блокировку, принудительно увеличивая версию A, что приведет к сбою второй попытки. На самом деле, поскольку A имеет ManyToOne to B, его версия должна увеличиваться, поэтому вы уже должны получить ошибку блокировки.

...