Apache Camel с Spring - управление транзакциями на маршруте - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть маршрут

from("direct:my-route")
        .routeId("id")
        .process(log(...))
        .transacted()            // Begin transaction
        .bean(...)   
        .bean(...)      
        .process(...)
        .bean(...)     
        .to("direct:end");       // End transaction

, который, как вы видите, находится в процессе транзакции.Все операции, выполняемые внутри Beans или Processors с использованием JdbcTemplate, обрабатываются.

У нас есть пользовательский ErrorHandler, который расширяет DeadLetterChannel, и я заметил, что когда генерируется исключение, транзакция все равно совершается.

Внутри TransactionTemplate#execute

TransactionStatus status = this.transactionManager.getTransaction(this);
T result;

try {
    result = action.doInTransaction(status);
}
catch (RuntimeException | Error ex) {
    // Transactional code threw application exception -> rollback
    rollbackOnException(status, ex);
    throw ex;
}
catch (Throwable ex) {
    // Transactional code threw unexpected exception -> rollback
    rollbackOnException(status, ex);
    throw new UndeclaredThrowableException(ex, "TransactionCallbac
}
this.transactionManager.commit(status);   <--- after doInTransaction
return result;

После вызова action.doInTransaction(status); поток кода просто переходит в this.transactionManager.commit(status), даже когда я выбрасываюRuntimeException.

Вызов action.doInTransaction(status) переходит на TransactionErrorHandler, в частности этот фрагмент кода

transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(TransactionStatus status) {
        // wrapper exception to throw if the exchange failed
        // IMPORTANT: Must be a runtime exception to let Spring regard it as to do "rollback"
        RuntimeException rce;

        // and now let process the exchange by the error handler
        processByErrorHandler(exchange);

        // after handling and still an exception or marked as rollback only then rollback
        if (exchange.getException() != null || exchange.isRollbackOnly()) {
...

processByErrorHandler, просто установите исключение Exchange на null, поэтому он не переброшен.


Извините за это "запутанное" вступление.У меня вопрос, как я могу явно откатить транзакцию в случае исключения?Какая стратегия лучше здесь?

...