【问题标题】:I cannot catch exceptions in method annotated @Transactional我无法在注解 @Transactional 的方法中捕获异常
【发布时间】:2017-12-04 15:59:08
【问题描述】:

我无法在注解为 @Transactional 的方法中捕获异常。 如果save 操作成功,我想向创建的用户发送邮件。

当用户名已经在使用时,PostgreSQL 抛出异常PSQLException 这是SQLExcpetion 的扩展,这是Exception 的扩展。我无法捕捉到ExceptionPSQLException,然后我尝试捕捉Throwable,这是有效的,但没有解决我的问题,并发现捕捉Throwable 是导致新问题的原因。

  1. 当我得到 DataIntegrityViolationException(这是 Spring 的一个异常)时,我想传播它,因为我的控制器有处理程序,它返回为此具体异常指定的语句和状态。当我捕获 Throwable 时,我必须总是抛出 RuntimeException。

  2. 很奇怪的是,即使抛出了一些异常,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


【解决方案1】:

遇到了同样的问题。已修复使用 saveAndFlush

这是有道理的,因为对于事务性,事务在执行函数后被提交(到 db)。但是saveAndFlush就不是这样了。

【讨论】:

    猜你喜欢
    • 2018-07-21
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2011-04-19
    • 2011-02-12
    相关资源
    最近更新 更多