Нет отката только для транзакции, когда в подметоде возникает исключение

Я использую аннотации Hibernate + spring + @Transactional для обработки транзакций в моем приложении.

Менеджер транзакций объявляется следующим образом:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

В большинстве случаев это работает хорошо, но я обнаружил проблему, когда у меня есть 2 метода, оба с аннотациями @Transactional:

package temp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

public class OuterTestService {
    @Autowired
    private InnerTestService innerTestService;

    @Transactional
    public void outerMethod() {
        try {
            innerTestService.innerTestMethod();
        } catch (RuntimeException e) {
            // some code here
        }
    }
}

и

package temp;

import org.springframework.transaction.annotation.Transactional;

public class InnerTestService {

    @Transactional
    public void innerTestMethod() throws RuntimeException {
        throw new RuntimeException();
    }
}

Когда я вызываю OuterTestService # outerMethod (), Я получаю исключение

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

Поскольку существует только одна транзакция (нет вложенных транзакций), вся транзакция outerTestMethod () помечена как откат только.

Я обнаружил, что могу легко преодолеть это с помощью noRollbackFor:

package cz.csas.pdb.be.service.tempdelete;

import org.springframework.transaction.annotation.Transactional;

public class InnerTestService {

    @Transactional(noRollbackFor = RuntimeException.class)
    public void innerTestMethod() throws RuntimeException {
        throw new RuntimeException();
    }
}

Но это должно явно использоваться для каждого метода . Поскольку эта ошибка не возникает во время тестов (которые откатываются), это неприемлемо.

Мой вопрос - есть ли способ автоматически (например, не явно для каждого метода) установить, что транзакции откатываются только тогда, когда исключение возникает из метода, который запустил транзакцию (в данном случае outerTestMethod () )?

6
задан Ondrej Skalicka 23 May 2011 в 12:13
поделиться