【发布时间】:2020-07-29 17:54:02
【问题描述】:
我有一个 @Transactional 标记类 FooServiceImpl,它需要使用从另一个 @Transactional 类 BarServiceImpl 获得的值填充对象 FooDetails。
当尝试从 BarServiceImpl 获取值时,会抛出 Exception1。我想将设置器抛出异常的 FooDetails 字段留空并捕获异常。所有其他字段必须 即使某些 setter 抛出异常,也会保持填充状态。
遗憾的是,事实并非如此,因为尽管我将方法明确标记为“noRollbackFor = Exception1.class”并捕获了异常,但由于抛出了 Exception1,事务已被标记为仅回滚。
为什么会发生这种情况,我如何修复代码以填充设置器未抛出异常的所有字段,并将设置器抛出异常的字段留空。 以下是导致该行为的代码:
@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());
}
}
}
【问题讨论】:
-
你能显示异常类吗?
-
@InsertKnowledge 没有什么特别的。只是带有扩展 Exception 的自定义错误消息的自定义异常。
标签: java spring spring-boot exception transactions