[Item 76] 가능한 한 실패 원자적으로 만들라

2022. 9. 26. 00:57JAVA/Effective Java

실패 원자적

  • 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 특성을 실패 원자적(failure-atomic)이라고 한다.

 

메서드를 실패 원자적으로 만드는 방법

  • 불변 객체를 설계한다.
    • 불변 객체는 생성 시점에 고정되어 절대 변하지 않기 때문에 기존 객체가 불안정한 상태가 빠지는 일은 없다.
  • 로직을 수행하기 전에 매개변수의 유효성을 검사한다.
    • 객체의 내부 상태를 변경하기 잠재적 예외의 가능성 대부분을 걸러낸다.
public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    elements[size] = null; // 다 쓴 참조 해제
    return result;
}
  • 실패할 가능성이 있는 모든 코드를, 객체의 상태를 바꾸는 코드보다 앞에 배치한다.
    • 로직을 수행하기 전에 인수의 유효성을 검사하기 어려울 때 사용할 수 있다. TreeMap을 예로 들면 잘못된 타입의 원소를 추가할 때 트리를 변경하기 앞서 해당 원소가 들어갈 위치를 찾는 과정에서 ClassCastException을 던진다.
  • 객체의 임시 복사본에서 작업을 수행한 후에 성공적으로 완료되면 원래 객체와 교체한다.
    • 데이터를 임시 자료 구조에 저장해 작업하는 것이 더 빠를 때 적용하기 좋은 방법이다. List 클래스의 compare 메서드가 그렇다. 정렬하기 전에 원소들을 배열에 옮겨 담고 그다음에 정렬을 수행한다.
  • 작업 도중에 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌린다.
    • 주로 디스크 기반의 내구성(durability)를 보장해야 하는 자료구조에 쓰이는데, 자주 사용되는 방법은 아니다.

 

실패 원자성을 지켜야 되나?

예를 들어 ConcurrentModificationException을 잡아냈더라도 그 객체가 여전히 사용할 수 있는 상태라고 가정해서는 안 된다. 따라서 권장되는 부분이긴 하지만 항상 실패 원자성을 지킬 수 있는 것은 아니다.

 

실패 원자적으로 만들 수 있어도 항상 그래야 하는 것도 아니다. 이를 달성하기 위한 비용이 크거나 복잡도가 아주 큰 연산이 있을 수 있기 때문이다. 이 규칙을 지키지 못한다면 실패 시의 객체 상태를 API 설명에 명시해야 한다.

 

따라서 Error는 복구할 수 없으므로 AssertionError에 대해서는 실패 원자적으로는 만들려는 시도도 필요가 없다.

 


핵심정리

  • 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 특성을 실패 원자적(failure-atomic)이라고 한다.
  • 메서드를 실패 원자적으로 만드는 방법은 여러가지가 있다.
    • 불변 객체를 설계한다.
    • 로직을 수행하기 전에 매개변수의 유효성을 검사한다.
    • 실패할 가능성이 있는 모든 코드를, 객체의 상태를 바꾸는 코드보다 앞에 배치한다.
    • 객체의 임시 복사본에서 작업을 수행한 후에 성공적으로 완료되면 원래 객체와 교체한다.
    • 작업 도중에 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌린다.
  • 항상 실패 원자성을 지킬 수 있는 것도 아니고 항상 지켜야 되는 것도 아니다. 이를 달성하기 위한 비용이 크거나 복잡도가 아주 큰 연산이 있을 수 있기 때문이다.

참고자료

www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=

 

이펙티브 자바 3/E - 교보문고

프로그래밍인사이트 | 자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브러리의 최신 기능을 십분 활용

www.kyobobook.co.kr