Spring:异常处理与 try catch 块的优先级不一致

Spring: Inconsistent precedence of exception handling vs try catch block

有 spring boot/jpa 申请。 在下面的代码中 - 如果 createEntity() 方法中的保存调用引发 DataIntegrityViolationException,则 异常在 EntityExceptionHandler 中被捕获 - 而不是在 catch(try-catch 的)块中。 如果从 createEntity 方法(服务 class)中删除 @Transactional 注释,则 DataIntegrityViolationException 是在 catch 块中捕获的,而不是在异常处理程序中。

这可以解释一下吗?我不明白其中的矛盾。

此外,如果在 EntityController 中的 createEntity 调用周围放置一个 try-catch 块,则异常 在 catch 块中被捕获 - 而不是在异常处理程序中 - 无论 @Transactional 是否 注释已设置。这也能解释一下吗?

谢谢。

public class EntityController {
    @PostMapping(value = "/entities")
    @ResponseBody
    public ResponseEntity postEntity(@RequestBody entity) {
        entityService.createEntity(entity);
        return ResponseEntity.status(HttpStatus.CREATED)...;
    }
}

@Repository("EntityRepository")
public interface EntityRepository extends JpaRepository<Entity, UUID> {}

@Service
public class EntityServiceImpl implements EntityService {
    @Autowired
    private EntityRepository entityRepository;

    @Override
    @Transactional
    public void createEntity() {
        Entity entity = new Entity(...);
        try {
            entityRepository.save(entity);
        } catch (DataIntegrityViolationException ex) {...}
    }
}

@ControllerAdvice
public class EntityExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(DataIntegrityViolationException.class)
    @ResponseBody
    public ResponseEntity<Object> handleDataIntegrityViolationException(DataIntegrityViolationException ex, WebRequest request) {
        return ResponseEntity.status(HttpStatus.CONFLICT).headers(new HttpHeaders()).body("");
    }
}

事务一提交到数据库就出现异常。 如果该方法用@Transactional 注释,则提交发生在“包装器”中,而不是在 createEntity 方法本身中。因此 try-catch 块无效。

带有@Transactional 的伪代码:

beginTransaction()
try {
  entityRepository.save(...)
} catch (....) {}
endTransaction() <- here the exception is thrown