비즈니스의 사용자 지정 예외에 대한 예외 또는 RuntimeException 이유는 무엇입니까?

본 글은 "골든스톤 프로젝트. 상금 6만원 공유" 에 참여하는 글입니다 .

순서

오늘은 동료들과 이상에 대해 수다를 떨다가 여기에 정리합니다.

 目前公司中使用的 自定义异常是 extend RuntimeException 

상속 예외

비즈니스 개발에서 예외를 상속받아 RuntimeException 또는 Exception을 확장합니까?

RuntimeException인 줄 알았는데 왜? 예외를 선택할 수 없습니까?

RuntimeException과 예외의 차이점

이것에 대해 이야기하기 전에 우리의 필요가 무엇인지 결정해야 합니다.

필요

요구 사항은 비즈니스에서 사용되는 예외 를 사용자 지정하는 것입니다.

요구 사항을 결정한 후 분석합니다.

image.png

여기서 우리는 비즈니스 개발이 기본적으로 런타임 예외라는 것을 알고 있으므로 RuntimeException을 사용합니다.

여기서 질문이 있는데요, 우리가 평소에 IO 연산을 할 때 유행을 타서 던지기나 잡기를 시도하는 경우가 많은데 어떤 속성을 하나요?

먼저 코드 조각을 살펴보십시오.

image.png

하지만 이 예외는 createNewFile 메서드에 의해 발생한 예외가 RuntimeException인지 여부와 관련이 없기 때문입니다.

public boolean createNewFile() throws IOException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) security.checkWrite(path);
    if (isInvalid()) {
        throw new IOException("Invalid file path");
    }
    return fs.createFileExclusively(path);
}
复制代码

관련이 있고 비 RuntimeException에는 throws 또는 try catch가 필요하지만 이것은 자동이 아니며 개발자가 코드를 작성할 때 수행해야 하는 작업이므로 이 예외를 확인 해야 합니다 .

기타 프로그래밍 언어 원칙 책 434페이지의 일부 참고

image.png

이 작품은 비즈니스에서 어떤 것을 사용할 것인지에 대한 질문을 남깁니다.

image.png

다른 RuntimeException 코드와 어떻게 다릅니까?

차이가 없습니다. 즉, 하나는 RuntimeException을 상속하고 다른 하나는 Exception을 상속하며 다른 것은 없습니다.

트랜잭션의 예외 가로채기

我们到这 知道了继承异常应该用RuntimeException,但是我们应该知道 阿里规约手册 中有这么一段

1、让检查异常也回滚:你就需要在整个方法前加上@Transactional(rollbackFor=Exception.class)

2、让非检查异常不回滚:
需要加入@Transactional(notRollbackFor=RunTimeException.class)

3、不需要事务管理(or 日志丢失)
需要加入@Transactional(propagation=Propagation.NOT_SUPPORTED)

为什么?

Exception类下面除了runtimeException还有SQLException和ioException

如果方法没有抛出runtimeException 而是抛出 SQLExceptionioException那么事务是不会回滚的

那么这就结束了吗?在我们编码过程中,如果方法要抛出一些可检查异常时是需要throws进行显式指定异常类的

那么问题来了,我们都知道方法签名中默认是throws RuntimeException,已知SqlException不是RuntimeException的子类

小总结

@Transactional(notRollbackFor=RunTimeException.class) 是因为抛弃了 IO异常和 SQL异常等情况,所以 我们 应该用 Transactional(rollbackFor=Exception.class)

为什么 不是 rollbackFor = Throwable.class 呢

이것을 명시적으로 지정할 필요는 없습니다 .  rollbackFor = Throwable.class 트랜잭션이 발생하면 스프링이 기본적으로 트랜잭션을 롤백하기 때문 错误입니다. **

원래 non-RuntimeException을 제외하고 나머지는 이미 트랜잭션 관리에 있음

기본 구성에서 Spring Framework의 트랜잭션 인프라 코드는 확인되지 않은 예외, 즉 RuntimeException의 인스턴스 또는 하위 클래스인 예외가 있는 런타임 롤백용 트랜잭션만 표시합니다.  (오류는 또한 기본적으로 롤백을 유발합니다) . 트랜잭션 메서드에서 throw된 확인된 예외는 기본 구성에서 롤백을 일으키지 않습니다. **

또는 보기 DefaultTransactionAttribute

public boolean rollbackOn(Throwable ex) { 
        return (ex instanceof RuntimeException || ex instanceof Error); 
}
复制代码

특정 위치 docs.spring.io/spring-frame…

요약하면 트랜잭션에 @Transactional(rollbackFor=Exception.class) 를 사용해야 합니다.

예외에 대한 다른 미들웨어의 애플리케이션 시나리오는 무엇이며 그 이유는 무엇입니까?

먼저 나코를 보세요

//检查 异常
public class NacosException extends Exception {
}
复制代码

사용할 때

image.png

던지기와 시도 잡기가 있습니다.

그렇다면 Nacos 예외는 무엇입니까?

private <T extends Response> T requestToServer(AbstractNamingRequest request, Class<T> responseClass)
        throws NacosException {
    try {
        xxx
    } catch (Exception e) {
        throw new NacosException(NacosException.SERVER_ERROR, "Request nacos server failed: ", e);
    }
    throw new NacosException(NacosException.SERVER_ERROR, "Server return invalid response");
}
复制代码

로켓엠큐

런타임 예외 먼저 살펴보기

运行时异常
public class AclException extends RuntimeException {
}
复制代码

사용

public static void verify(String netaddress, int index) {
    if (!AclUtils.isScope(netaddress, index)) {
        //运行的时候 发生异常
        throw new AclException(String.format("Netaddress examine scope Exception netaddress is %s", netaddress));
    }
}
复制代码

다른 확인된 예외 보기

public class MQClientException extends Exception {
}
复制代码
throws MQClientException, RemotingException, MQBrokerException
复制代码

사용

public TransactionSendResult sendMessageInTransaction(final Message msg,
    final LocalTransactionExecuter localTransactionExecuter, final Object arg)
    throws MQClientException {
    TransactionListener transactionListener = getCheckListener();
    if (null == localTransactionExecuter && null == transactionListener) {
        //如果为空 client 异常
        throw new MQClientException("tranExecutor is null", null);
    }
 }
复制代码

요약하다

대부분의 미들웨어는 클라이언트 연결 실패, 원격 연결 시간 초과, 서버 측 예외 등 검사 시 예외 사항이므로 Exception을 확장해야 합니다.

하지만

  1. 비즈니스 개발 중에는 대부분의 판단이 비어 있으며 RunntimeException이 런타임 예외인 것이 좋습니다.
  2. 예외는 점검하는 동안 항상 던져야 하며, RunntimeException은 코드 청결의 관점에서 권장됩니다.

요약하다

  1. 원격접속 사용/비정상사용 체크는 비정상으로 상대방이 이상함을 느낄 수 있도록
  2. 비즈니스 코드는 런타임 예외를 사용합니다.

비즈니스용으로 extends RuntimeException 을 사용하는 것이 여전히 권장되며 나머지는 비즈니스 시나리오에 따라 선택해야 합니다.

생각한다

 ok 那你说 远程连接使用 检查时异常,那feign 属于远程rpc,他的异常就必须是 检查时异常么?为什么? 

Supongo que te gusta

Origin juejin.im/post/7166976169152086024
Recomendado
Clasificación