가능한 한 실패 원자적으로 만들라메서드를 실패 원자적으로 만드는 방법.1️⃣ 불변 객체로 설계하자.2️⃣ 매개변수의 유효성을 검사하자.3️⃣ 객체의 임시 복사본에서 작업을 수행한 후 성공하면 원래 객체와 교체하자.4️⃣ 작업 도중에 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌리자.실패 원자성을 항상 달성시켜야 하는 것일까?실패 원자성을 만들 수 있으면 항상 만들어야 할까?결론
가능한 한 실패 원자적으로 만들라
호출된 메서드가 실패 하더라도 객체는 메서드 호출 전 상태를 유지해야 한다. 이러한 특성을 실패 원자적(failure atomic) 이라고 표현한다.
메서드를 실패 원자적으로 만드는 방법.
1️⃣ 불변 객체로 설계하자.
- 불변객체는 태생적으로 실패 원자적이다. 메서드가 실패하면 새로운 객체로 만들어지지 않을 수 있으나 기존 객체가 불안정한 상태에 빠지는 일은 없다.
- String 클래스의 subString 메서드를 살펴보면 실패 원자적으로 만들어져 있습니다.
- 기존 객체가 불안정한 상태에 빠지지 않는다.
- 시작 인덱스가 0보다 작거나, 시작 인덱스가 끝 인덱스보다 크거나, 끝 인덱스가 현재 문자 길이보다 긴 경우에는 예외가 발생한다.


2️⃣ 매개변수의 유효성을 검사하자.
- 객체의 내부 상태를 변경하기 전에 잠재적 예외의 가능성을 대부분 걸러낼 수 있다.
- 아래는 stack의 pop 메서드이다. 코드를 보면 작업을 수행하기 전 index가 현재 원소의 수를 비교하는 작업을 진행하여 검사를 하고 있다.


- 실패할 가능성이 있는 모든 코드를 객체의 상태를 바꾸는 코드보다 앞에 배치하는 방법도 존재한다.
- 로직을 수정하기 전에 인수의 유효성을 검사하기 어려울 때 사용할 수 있으며 TreeMap을 예로 들어 잘못된 타입의 원소를 추가할 때 트리를 변경하기에 앞서 해당 원소가 들어갈 위치를 찾는 과정에서 ClassCastException을 던질 것이다.
3️⃣ 객체의 임시 복사본에서 작업을 수행한 후 성공하면 원래 객체와 교체하자.
- 데이터를 임시 자료구조에 저장해 작업하는게 더 빠를 경우 적용하기 좋은 방식이다.
- 예를들어 List의 Sort 메서드가 해당된다 정렬하기 전에 원소들을 배열에 옮겨 닮고 그 다음에 정렬을 수행하도록 되어있다.

4️⃣ 작업 도중에 발생하는 실패를 가로채는 복구 코드를 작성하여 작업 전 상태로 되돌리자.
- 이 방법은 주로 디스크 기반의 내구성을 보장해야 하는 자료구조에 쓰이게 되는데 자주 쓰이는 방법은 아니다.
실패 원자성을 항상 달성시켜야 하는 것일까?
- 실패 원자성은 일반적으로 권장되는 부분이지만 항상 달성할 수 있는 것은 아니다.
- 두 스레드가 동기화 없이 같은 객체를 동시에 수정한다면 그 객체의 일관성이 깨질 수 있다.
- Error는 복구할 수 없기 때문에 AssertionError에 대해서는 실패 원자적으로 만들려는 시도조차 할 이유가 없다.
실패 원자성을 만들 수 있으면 항상 만들어야 할까?
- 실패 원자적으로 만들 수 있더라도 항상 정답은 아니다.
- 실패 원자성을 달성하기 위한 비용이나 복잡도가 아주 큰 연산도 있기 때문이다.
- 그럼에도 문제가 무엇인지 알고 나면 실패 원자성을 공짜로 얻을 수 있는 경우가 많다.
- 메서드 명세에 기술한 예외라면 설혹 예외가 발생하더라도 객체의 상태는 메서드 호출 전과 똑같이 유지되어야 한다는 것이 기본 규칙이다.
- 이 규칙을 지키지 못한다면 실패 시의 객체 상태를 API 설명에 명시해야 한다. 이것이 이상적이나 아쉽게도 API 문서 상당이 잘 지켜지지 않고 있다.
결론
- 실패 원자적은 호출된 메서드가 실패하더라도 해당 객체는 호출 전 상태를 유지해야하는 특성이다.
- 그 특성을 갖기 위한 방법은 크게 네가지가 있었다.
- 불변객체
- 매개변수 검사
- 임시복사본 만들기
- 복구코드 작성
- 원자성을 보장할 수 없을 때가 있다.
- 두 스레드가 동기화 없이 같은 객체를 동시에 수정할 때
- Error
- 원자성을 최대한 보장해주는게 좋지만 항상 그런것은 아니다 비용이 높거나 복잡하다면 한번 더 생각해보자.
- 또한 그러한 부분은 API 명세에 적어두자 (지키지 않는곳이 많다고 하니 우리는 작성합시당…😎)