Предположим, что у нас есть база данных (например, Oracle) и поставщик JMS (например, HornetQ), участвующий в транзакции XA. Сообщение отправляется в очередь JMS, а некоторые данные сохраняются в базе данных в той же распределенной транзакции. После совершения транзакции потребитель сообщения будет считывать сохраненные данные и обрабатывать их в отдельной транзакции.
В отношении первой транзакции XA диспетчер транзакций (например, JBoss) может выполнять следующую последовательность событий
- подготовить (HornetQ)
- подготовить (Oracle)
- commit (HornetQ)
- commit (Oracle)
Что произойдет, если потребитель сообщения начнет считывать данные после завершения коммита в HornetQ, но все еще выполняется в Oracle? Будет ли пользователь сообщения читать устаревшие данные?
Вопрос может быть обобщен на любой вид нескольких ресурсов, участвующих в транзакциях XA, т.е. существует возможность для небольшого временного окна (когда выполняются фазы фиксации), в котором читатель из другой параллельной транзакции может получить несогласованное состояние ( путем считывания данных с одного ресурса и устаревших данных из другого)?
Я бы сказал, что единственный способ для транзакционных ресурсов предотвратить это - заблокировать всех читателей затронутых данных, как только этап подготовки будет завершен до тех пор, пока не будет произведена фиксация. Таким образом, примерный потребитель сообщения, упомянутый выше, блокируется до тех пор, пока данные не будут переданы в базу данных.