Я ищу шаблон общего кода для надлежащей обработки транзакции относительно возможного исключения. Я предполагаю, что существует общий шаблон кода для этого, с каким конкретным видом транзакции мы имеем дело.
У меня есть метод, который выполняет что-то в транзакции, и хотят повторно бросить Исключение, которое может произойти когда в транзакционном блоке кода. Вот пример такого метода:
protected void doIt() {
// for JDBC connection transaction may be started automatically
// but assume we start it here
Tran tran = session.beginTran();
try {
// here comes code that does some processing
// modifies some data in transaction
// etc.
// success - so commit
tran.commit();
} catch (Exception ex) { // many different exceptions may be thrown
// subclass of RuntimeException, SQLException etc.
// error - so rollback
tran.rollback();
// now rethrow ex
throw ex; // this line causes trouble, see description below
}
}
Теперь - в методе существует ошибка компиляции doIt
. Это должно объявить throws Exception
но это не приемлемо потому что метод doIt
используется во многих местах и добавлении throws Exception
приводит к последующим модификациям в местах прямого и косвенного использования doIt
. Это из-за известной проблемы проектирования Языка Java с объявленными исключительными ситуациями.
Теперь вопрос: как измениться, исключение по сравнению с кодом обработки транзакции для достижения моей цели - правильно обрабатывают завершение транзакции (выполните фиксацию или откат на основе условия успеха), и повторно бросьте точно то же исключение, которое может быть поймано в транзакционном блоке кода.
Я знаю, что мог сделать что-то как throw new RuntimeException(ex)
но это выдает исключение другого класса, и я хочу избежать такого решения.
Я бы пошла на что-нибудь подобное.
protected void doIt() {
// for JDBC connection transaction may be started automatically
// but assume we start it here
Tran tran = session.beginTran();
bool success = false;
try {
// here comes code that does some processing
// modifies some data in transaction
// etc.
// success - so commit
tran.commit();
success = true;
} finally {
// error - so rollback
if (! success)
tran.rollback();
}
}
... или если у tran есть метод, в котором можно запросить статус (tran.isFinished()) или что-то в этом роде, вам не нужен bool. Любое брошенное исключение (т.е. runtimeexception или ошибка, если нет проверенных исключений) будет просто пролетать мимо, выполняя в конце концов блок на пути вверх по стеку.
Если откат бросает исключения, то нужно перехватить их и лог-ем или что-то в этом роде (неудачный откат - очень серьезное условие). Не забывайте бросать что-либо в этом случае, так как исключение, которое в данный момент разворачивает стек, будет потеряно.
Предполагая, что вы используете Java 5+, пружинная структура имеет простую аннотацию (@transactional), вы можете использовать для настройки транзакций.
Это фрагмент того, какое начало вашего кода вы похоже, если вы хотите откатиться с любым исключением:
import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = Exception.class)
protected void doIt()
Следующая ссылка может помочь вам начать, если вы хотите использовать это: http: / /static.springsource.org/spring/docs/2.0.x/reference/transaction.html. Раздел 9.5.6 - это определенный раздел для использования @transactional.