2014-01-17 2 views
3

Интересно, имеет ли смысл использовать вместоСпринг сделка: откат на исключение или Throwable

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) 

использовать Throwable

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) 

Как я понимаю, ловя Error поможет нам правильно вести себя, даже если что-то действительно плохое. Или, может быть, это не поможет?

ответ

9

Как я понимаю, ошибка лова поможет нам правильно вести себя, даже если что-то действительно плохое. Или, может быть, это не поможет?

Вам не нужно явно указать rollbackFor = Throwable.class, потому что весна будет по умолчанию откатить транзакцию, если Error происходит.

См 12.5.3 Rolling back a declarative transaction

В конфигурации по умолчанию код транзакционной инфраструктуры Spring Framework, только помечает транзакцию для отката в случае выполнения, непроверенные исключения; то есть, когда выбрано исключение является экземпляром или подклассом RuntimeException. (Ошибки также - по умолчанию - результат откат). Проверенные исключения, возникающие из транзакционного метода, не приводят к откату в конфигурации по умолчанию.

Или взгляните на DefaultTransactionAttribute

public boolean rollbackOn(Throwable ex) { 
    return (ex instanceof RuntimeException || ex instanceof Error); 
} 
+0

Это полезная информация. Благодарю. –

4

Поскольку вы используете @Transactional, мы можем с уверенностью предположить, что вы выполняете операции с базой данных через Spring, Hibernate или другие обертки JDBC. Эти обертки JDBC обычно не выдают проверенные исключения, они вызывают исключения во время выполнения, которые обертывают типы JDBC SQLException.

@Transactional - это настройка отката по умолчанию только при выделении непроверенного исключения.

Рассмотрим случай использования как так

@Transactional 
public void persistAndWrite(Bean someBean) throws IOException{ 
    getSession().save(someBean); // DB operation 
    someFileService.writeToFile(someBean); File IO operation which throws IOException 
} 

Вы не обязательно хотите откатить операцию DB только потому, что мы не могли бы написать что-то в файл.

Аналогично

@Transactional 
public void persistAndThrowOutOfMemory(Bean someBean) { 
    getSession().save(someBean); // DB operation 
    someService.hugeOperationThrowsOutOfMemoryError(); // consumes all memory, throws OutOfMemoryError 
} 

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

@Transactional дает вам возможность. Используйте его там, где это необходимо.

+1

Если я отметил этот метод как сделки - то я уверен, что я хочу, чтобы откатить на некоторых жестких ошибок. Но если это вообще будет работать и считается хорошей практикой? –

+0

@igor Это откат при выполнении исключений во время выполнения и все остальное, что вы скажете, чтобы откат. Обычно не рекомендуется перехватывать что-либо другое, кроме типов «Исключение» и «RuntimeException». –

+0

Почему не рекомендуется проверять откаты на Error/RuntimeException? – Guillaume

-1

Я не знаю, возможно ли это или нет, но обработка Throwable s как Error s - плохой стиль программирования, ответственность разработчиков за такие фатальные ошибки не несет разработчики. Всегда могут происходить плохие вещи, с которыми вы не справитесь. При необходимости вы должны обрабатывать проверенные исключения, которые известны вашей системе, как некоторые логические ошибки.

Смежные вопросы