Как я могу прикрепить данные к транзакции JTA? (или однозначно идентифицировать его)

У меня есть функция getStockQuote(), которая получает текущую котировку акций для символа с фондового рынка.

Моя цель состоит в том, чтобы в транзакции JTA первый вызов getStockQuote() извлекал котировку акций, но все последующие вызовы в рамках одной и той же транзакции будут повторно использовать одну и ту же котировку акций (например, она не будет пытаться получить новую котировку). Если запускается другая транзакция или другая транзакция выполняется одновременно, я ожидаю, что другая транзакция получит свою собственную котировку акций при первом вызове.

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

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

Есть ли у кого-нибудь советы о том, как этого можно достичь?


person kwyjibo    schedule 17.05.2010    source источник
comment
Я могу восстановить свой ответ позже, но ваш комментарий был правильным, и с текущим уровнем детализации я не могу уточнить. Используете ли вы EJB? Как управляются транзакции?   -  person Pascal Thivent    schedule 18.05.2010
comment
По сути, весь этот код выполняется внутри сеансовых компонентов EJB3 без сохранения состояния, а транзакции управляются с помощью транзакций, управляемых контейнером.   -  person kwyjibo    schedule 18.05.2010


Ответы (2)


Это потребует некоторого тестирования, но я думаю, что вы могли бы привязать цитату к ThreadLocal и заставьте свои компоненты реализовать SessionSynchronization, чтобы отвязать цитату от ThreadLocal после фиксации транзакции (и, таким образом, реализовать своего рода контекст области транзакции).

person Pascal Thivent    schedule 17.05.2010
comment
Насколько я понимаю, один поток может использоваться для двух транзакций, например: транзакция A начинается, я получаю котировку акций, я использую кешированную котировку акций, транзакция A заканчивается. транзакция B затем начинается в том же потоке, как я узнаю, что мне нужно получить новую цитату? - person kwyjibo; 18.05.2010
comment
именно здесь появляется SessionSynchronization. В вашем методе afterBegin() вы инициализируете объект, а в afterCompletion() вы завершаете его (на самом деле будет достаточно только инициализации, если вам не нужно закрывать какие-либо ресурсы) - person Sean Patrick Floyd; 18.05.2010
comment
Интерфейс SessionSynchronization был именно тем, что я искал, спасибо. - person kwyjibo; 18.05.2010
comment
@seanizer Согласен, здесь должно быть достаточно инициализации в afterBegin. - person Pascal Thivent; 19.05.2010

рассмотрите возможность использования Spring для управления транзакциями, он предоставляет эту функциональность из коробки:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-propagation

person Sean Patrick Floyd    schedule 17.05.2010
comment
Я не вижу никаких ссылок на хранение пользовательских данных в этой документации. - person kwyjibo; 18.05.2010
comment
позвольте мне перефразировать это: он предоставляет инструменты, необходимые для создания такой функциональности. Пользовательские менеджеры транзакций, обратные вызовы транзакций, вспомогательные утилиты для поиска текущей транзакции — существует множество способов сделать это. Извините за неадекватный ответ - person Sean Patrick Floyd; 18.05.2010