Я хотел бы добавить одну вещь.Большинство исключений (99,999%) означают, что с вашим кодом или средой что-то не так, что требует внимания администратора.Если ваш код не может подключиться к базе данных, возможно, это неправильно сконфигурированная среда, нет смысла пытаться повторить его, просто чтобы узнать, что он не работает 3-й, 4-й или 5-й раз.Если вы выбрасываете исключение из-за того, что человек не указал действительный номер кредитной карты, повторная попытка не будет волшебным образом заполнять номер кредитной карты.
Единственные ситуации, которые стоит повторить удаленно, это когдасистема чрезвычайно напряжена, и время истекает, но в этой ситуации логика повторных попыток, вероятно, вызовет большую нагрузку, чем меньшую (3 раза за 3 попытки на каждую транзакцию).Но это то, что системы делают, чтобы снизить спрос (см. Историю миссии Apollo Lander).Когда систему просят сделать больше, чем она может, она начинает сбрасывать задания, и тайм-ауты являются сигналом того, что система перегружена (или плохо написана).Вы бы оказались в гораздо лучшем положении, если бы просто увеличили емкость своей системы (добавьте больше оперативной памяти, увеличьте количество серверов, добавьте больше серверов, улучшите алгоритмы, масштабируйте ее!).
Другая ситуация будет, если выВы используете оптимистическую блокировку, и вы можете как-то восстановить и автоматически объединить две версии объекта.Хотя я видел это раньше, я бы предостерег этот подход, но это можно сделать для простых объектов, которые можно объединять без конфликтов в 100% случаев.
Большинство логик исключений должно быть перехвачено на соответствующем уровне (очень важно), убедитесь, что ваша система находится в хорошем согласованном состоянии (например, транзакции отката, закрытие файлов и т. д.), зарегистрируйте ее, сообщите пользователю, что она не работает.попробуйте дать хорошую основу (ну, потому что это весело, как кроссворд).
// client code - what you write a lot
public class SomeDao {
public SomeReturn saveObject( final SomeObject obj ) throws RetryException {
Retry<SomeReturn> retry = new Retry<SomeReturn>() {
public SomeReturn execute() throws Exception {
try {
// doSomething
return someReturn;
} catch( SomeExpectedBadExceptionNotWorthRetrying ex ) {
throw new NoRetryException( ex ); // optional exception block
}
}
}
return retry.run();
}
}
// framework - what you write once
public abstract class Retry<T> {
public static final int MAX_RETRIES = 3;
private int tries = 0;
public T execute() throws Exception;
public T run() throws RetryException {
try {
return execute();
} catch( NoRetryException ex ) {
throw ex;
} catch( Exception ex ) {
tries++;
if( MAX_RETRIES == tries ) {
throw new RetryException("Maximum retries exceeded", ex );
} else {
return run();
}
}
}
}