Search

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

생성일
2023/08/15 07:04
챕터
10장 - 예외

요약

객체의 메서드들을 실패 원자적 상태로 만들 수 있는지 고려해보자.

실패 원자적

호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 특성을 실패 원자적(failure-atomic)이라 한다.
실패 원자적으로 만들면 작업 도중 예외가 발생해도 해당 객체를 여전히 정상적으로 사용할 수 있고, 검사 예외라면 호출자가 오류 상태를 복구할테니 더 유용하다.
메서드를 실패 원자적으로 만드는 방법은 여러가지가 있다.
객체를 불변 객체로 설계하기
불변 객체는 그 자체로 실패 원자적이고, 불안정한 상태에 빠지는 일이 없기 때문이다.
가변 객체라면 작업 수행 전에 매개변수의 유효성을 검사하기
객체의 내부 상태를 변경하기 전 잠재적 예외 가능성을 대부분 걸러낼 수 있다.
실패할 가능성이 있는 모든 코드를 객체 상태를 바꾸는 코드보다 앞에 배치하기
계산을 수행해보기 전에 인수의 유효성을 검사할 수 없을 때 덧붙여 사용할 수 있는 방법이다.
객체의 임시 복사본에서 작업을 수행한 다음 작업이 성공적으로 완료되면 원래의 객체와 교체하기
데이터를 임시 자료구조에 저장해 작업하는게 더 빠를 때 적용하기 좋은 방식이다.
작업 도중 발생하는 실패를 가초래는 복구 코드를 작성하여 작업 전 상태로 되돌리기
주로 내구성(durability)을 보장해야 하는 자료구조에 사용되는데, 자주 쓰이는 방법은 아니다.
실패 원자성은 일반적으로 권장되지만, 항상 달성할 수는 없다.
예를 들면, 두 스레드가 동기화 없이 같은 객체를 수정할 때 ConcurrentModificationException을 잡아냈다해서 해당 객체가 여전히 쓸 수 있는 상태인지는 알 수 없다.
또한 Error는 복구할 수 없으므로 AssertionError에 대해서는 실패 원자적으로 만들려는 시도조차 할 필요가 없다.
또한 실패 원자성을 달성하기 위한 비용이나 복잡도가 큰 경우에는 하지 않는게 더 나을 수도 있다. 이런 경우에는 실패 시의 객체 상태를 API 설명에 명시해야 한다.