【发布时间】:2017-12-04 15:59:08
【问题描述】:
我无法在注解为 @Transactional 的方法中捕获异常。
如果save 操作成功,我想向创建的用户发送邮件。
当用户名已经在使用时,PostgreSQL 抛出异常PSQLException 这是SQLExcpetion 的扩展,这是Exception 的扩展。我无法捕捉到Exception 和PSQLException,然后我尝试捕捉Throwable,这是有效的,但没有解决我的问题,并发现捕捉Throwable 是导致新问题的原因。
当我得到 DataIntegrityViolationException(这是 Spring 的一个异常)时,我想传播它,因为我的控制器有处理程序,它返回为此具体异常指定的语句和状态。当我捕获 Throwable 时,我必须总是抛出 RuntimeException。
很奇怪的是,即使抛出了一些异常,
emailSender.sendEmail()也会被调用。但是如果userRepository抛出异常,则不应调用任何方法,并且应在catch语句中捕获异常,然后回滚事务。我是否正确理解交易?
我的服务的实现:
@Transactional
public UserEntity createUser(UserEntity user) {
try {
final UserEntity saved = userRepository.save(user);
emailSender.sendEmail(saved);
return saved;
} catch (Throwable t) {
throw new RuntimeException();
}
return null;
}
当我尝试使用 IDEA 调试此方法时,调试器不会进入 catch 语句,但我的处理程序注释 @RestControllerAdvice 正在捕获此异常。
知道出了什么问题,或者你知道类似的问题吗?
【问题讨论】:
-
Spring 的
@Transactional将从实际方法抛出的异常包装到它自己的异常层次结构中。这就是您无法捕获SQLException或任何其他实际抛出的异常的原因。请查看文档:docs.spring.io/spring/docs/4.2.x/spring-framework-reference/… -
用@Transactional 注释执行catch 块的任何方法??
标签: spring transactions rollback