У меня есть помеченный @Transactional класс FooServiceImpl, который должен заполнить объект FooDetails значениями, полученными из другого класса @Transactional BarServiceImpl.
При попытке получить значения из BarServiceImpl выбрасывается исключение 1. Я хотел бы оставить поле FooDetails, установщик которого выбросил исключение, и перехватить исключение. Все остальные поля должны оставаться заполненными, даже если какой-то установщик выдал исключение.
К сожалению, это не так, потому что транзакция была помечена как только для отката из-за того, что было сгенерировано Exception1, хотя я явно пометил метод как "noRollbackFor = Exception1.class" и перехватил исключение.
Почему это происходит и как я могу исправить код, чтобы заполнить все поля, чьи установщики не генерировали исключение, и оставить пустыми те, чьи установщики бросили одно. Вот код, который приводит к поведению:
@Service
@Transactional
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TransactionalService {
// The name of the service
String value() default "";
}
public class FooDetails {
private String fieldA;
private String fieldB;
// getters and setters
...
}
@TransactionalService
public class BarServiceImpl implements BarService {
@Override
public String getFieldB() throws Exception1 {
...
try {
...
} catch (Exception2 e2) {
...
throw new Exception1();
} catch (Exception3 e3) {
...
throw new Exception1();
}
}
}
@TransactionalService
public class FooServiceImpl implements FooService {
...
...
@Autowired BarService barService;
@Override
@Transactional(noRollbackFor = {Exception1.class, Exception2.class, Exception3.class})
public FooDetails getFooDetails(Long fooId) {
Foo foo = fooDao.get(fooId);
if (foo == null) {
return null;
}
FooDetails fooDetails = new FooDetails();
// getAFooDetails() has no exceptions to throw => ok
fooDetails.setFieldA(getAFooDetails());
// barService.getFieldB() throws an Exception1 => results in
// "org.springframework.transaction.UnexpectedRollbackException:
// Transaction rolled back because it has been marked as rollback-only" => all foo fields left empty
try {
fooDetails.setFieldB(barService.getFieldB());
} catch (Exception1 e) {
LOG.info(e.getMessage());
}
}
}