Связь между Spring @ Transactional и транзакцией Camel

#apache-camel #spring-transactions #spring-camel

#apache-camel #spring-транзакции #spring-верблюд

Вопрос:

Если camel DSL помечен как transacted(), то действительно ли нам нужно помещать аннотацию @Transactional в метод Spring service?

Я действительно хочу знать, как взаимодействуют транзакции Camel и Spring.

Любая помощь будет высоко оценена.

Комментарии:

1. Если вы хотите подробно ознакомиться с транзакциями Camel, я настоятельно рекомендую Camel in Action 2nd edition .

2. Да, для углубленного изучения в этой книге есть целая глава о транзакциях, которая занимает более 35 страниц.

Ответ №1:

TL; DR

нет, как правило, вам не нужно комментировать какой-либо метод @Transactional , чтобы транзакции Camel работали.

Основное взаимодействие между Camel и Spring TransactionManager заключается в том, что Camel делегирует обработку транзакций Spring txManager, если он настроен на это. Другими словами: Camel использует Spring txManager, если он доступен, но вы также можете использовать другие txManagers.

Для этого делегирования никакие @Transactional аннотации не требуются. Вместо этого вам нужно настроить Spring txManager и пометить маршрут Camel как transacted() .

Длинная история

Однако ваш вопрос оставляет место для предположений. Каким методом вы хотите аннотировать @Transactional ? Метод, который содержит маршрут? Метод управляемого компонента, который вызывается маршрутом? Метод, полностью независимый от маршрута Camel?

Транзакционный маршрут Camel создает область транзакции вокруг всего маршрута (1) или, более конкретно, единицы работы.

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

Благодаря области транзакции уже «отправленные» (исходящие) сообщения не фиксируются до тех пор, пока транзакция не завершится успешно. После отката то же самое сообщение (входящее) повторно доставляется брокером и снова обрабатывается маршрутом.

Обратите внимание, что маршрут Camel может выполняться без transacted() маркера (2) в маршруте.

Однако, поскольку Camel связан с интеграцией, у вас часто возникают «смешанные среды», такие как JMS для базы данных. Или, что еще хуже, вы выполняете HTTP-запросы во время маршрута. Если ошибка возникнет позже, вы не сможете «отменить» эти вызовы.

Таким образом, в мире Camel транзакции могут очень помочь, но часто их недостаточно. Вы должны реализовать компенсации, чтобы иметь возможность действительно откатить прерванную обработку маршрута.

Если вы используете транзакционные маршруты, обязательно напишите маршрутные тесты, которые имитируют ошибки при обработке маршрута и проверяют, работает ли откат так, как вы ожидаете.

Что ж, это несколько высокоуровневых мыслей о Camel и транзакциях. Если вы хотите погрузиться глубже, возьмите книгу Camel, которую я рекомендовал в комментариях 🙂

Примечания:

(1) Когда маршрут содержит компоненты с отслеживанием состояния или EIP (например, агрегатор, ресеквенсор и т.д.), Они вводят границы транзакций внутри маршрута Camel. В таких случаях область транзакции заканчивается на первом компоненте с отслеживанием состояния. Как следствие, эти компоненты обычно предлагают необязательное сохранение, чтобы обеспечить возможность сохранения состояния.

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

(2) Например, с потребителем JMS, который использует локальные транзакции JMS.