Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item76. 가능한 한 실패 원자적으로 만들라 #73

Open
Mingadinga opened this issue Aug 29, 2023 · 0 comments
Open

Item76. 가능한 한 실패 원자적으로 만들라 #73

Mingadinga opened this issue Aug 29, 2023 · 0 comments

Comments

@Mingadinga
Copy link
Member

개발할 때 참고하면 좋을 팁인 듯! 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 특성을 실패 원자성이라고 한다. 예외가 발생해도 객체를 여전히 정상적으로 사용할 수 있다면 문제 복구에 활용할 수 있다. 불변 객체로 만들거나, 매개변수 유효성을 검사하거나, 임시 복사본에서 작업을 수행하거나, 복구 코드를 작성한다. 실패 원자성을 달성할 수 없다면 실패 시의 객체 상태를 API 설명에 명시해야한다.

실패 원자성

  • 실패 원자성 : 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 성질
  • 검사 예외를 던진 경우라면 호출자가 오류 상태를 복구할 수 있으므로 유용하다.
  • 메서드 명세에 기술된 예외라면, 예외가 발생하더라도 객체의 상태는 메서드 호출 전과 똑같이 유지돼야 한다는 것이 기본 규칙이다.

실패 원자성을 달성하는 방법

  1. 불변 객체로 만들기 : 불변 객체는 태생적으로 실패 원자적이다. 생성 시점에 객체의 상태가 고정되어 절대 변하지 않음

  2. 가변 객체라면, 작업 수행에 앞서 매개변수 유효성 검사 : 내부 상태를 변경하기 전에 잠재적 예외의 가능성 대부분을 걸러내는 방법. 예를 들어 Stack.pop에서 size == 0인지 먼저 검사해 EmptyStackException 예외를 던진다.

  3. 실패할 가능성이 있는 모든 코드를 객체의 상태를 바꾸는 코드보다 앞에 배치 : TreeSet은 내부 컬렉션에 요소를 추가하기 전에, 추가 가능한 타입인지 검사

  4. 객체 임시 복사본에서 작업 수행 후 원래 객체와 교체 : 정렬 작업을 수행하기 전에 입력 리스트를 배열에 옮겨 수행한다. 성능을 높일 수 있고, 설령 배열에서 정렬 작업이 실패해도 원본 리스트에는 영향이 없다.

  5. 실패를 가로채는 복구 코드 작성 : 복구 코드를 실행해서 작업 전 상태로 되돌리는 방법. 주로 디스크 기반의 내구성을 보장해야하는 자료구조에 사용하는데, 자주 쓰이지는 않음

실패 원자성을 달성할 수 없다면?

실패 원자성을 달성할 수 없는 경우

  • 두 스레드가 동기화 없이 같은 객체를 동시에 수정하는 경우, 객체의 일관성이 깨진다. 예외를 잡아낸다고 하더라도 그 객체가 여전히 쓸 수 있는 상태라고 가정하면 안된다.
  • Error(시스템 에러)는 복구할 수 없으므로, Error에 대해서는 실패 원자적으로 만드려는 시도조차 할 필요가 없다.
  • 실패 원자성을 달성할 수 있더라도, 원자성을 달성하기 위한 비용이나 복잡도가 큰 연산을 실행해야한다면 비효율적이다.

실패 원자성을 달성할 수 없다면?

→ 실패 시의 객체 상태를 API 설명에 명시해야한다! (잘 지켜지지 않는 경우가 많음)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant