자원에 대한 접근 방식으로도 이러한 경고가 존재하는 이유에 대한 개념적인 답변이 될 것입니다. 불행히도 달성하려는 쉬운 솔루션이 아닙니다.
오류 복구 실패
finally
트랜잭션의 성공 여부에 관계없이 실행되는 트랜잭션 후 제어 플로우를 모델링합니다.
실패한 경우, 오류가 완전히 복구되기 전에 ( 대상에 도달하기 전에) 오류 복구 도중에finally
실행되는 논리를 캡처합니다 .catch
오류 복구 중 오류가 발생하는 개념적 문제를 상상해보십시오 .
트랜잭션을 커밋하려고하는 데이터베이스 서버가 중간에 메모리 부족으로 인해 실패한다고 가정합니다. 이제 서버는 아무 일도 일어나지 않은 것처럼 트랜잭션을 특정 시점으로 롤백하려고합니다. 그러나 롤백 과정에서 또 다른 오류가 발생한다고 상상해보십시오. 이제 데이터베이스에 반 커밋 된 트랜잭션이 생겼습니다. 트랜잭션의 원자 성과 불가분의 특성이 이제 깨져서 데이터베이스의 무결성이 손상됩니다.
이 개념적 문제는 수동 오류 코드 전파를 사용하는 C인지, 예외 및 소멸자를 사용하는 C ++인지 또는 예외 및를 사용하는 Java인지에 관계없이 오류를 처리하는 모든 언어에 존재합니다 finally
.
finally
예외가 발생하는 과정에서 소멸자가 C ++에서 실패 할 수없는 것과 같은 방식으로 언어를 제공 할 수 없습니다.
이 개념적이고 어려운 문제를 피할 수있는 유일한 방법은 트랜잭션을 롤백하고 중간에 리소스를 해제하는 과정에서 재귀 예외 / 오류가 발생하지 않도록하는 것입니다.
따라서 여기서 안전한 디자인은 writer.close()
실패 할 수없는 디자인 입니다. 일반적으로 설계 중에 복구 도중 실패 할 수있는 시나리오를 피할 수있는 방법이 있으므로 불가능합니다.
불행히도 유일한 방법은 오류 복구에 실패 할 수 없습니다. 이를 보장하는 가장 쉬운 방법은 이러한 종류의 "리소스 릴리스"및 "역 부작용"기능이 실패 할 수 없도록하는 것입니다. 쉽지 않습니다. 적절한 오류 복구가 어렵고 불행히도 테스트하기가 어렵습니다. 그러나이를 달성하는 방법은 프로세스에서 "파기", "닫기", "종료", "롤백"등의 외부 오류가 발생할 수없는 기능이 있는지 확인하는 것입니다. 기존 오류에서 복구하는 동안 호출됩니다.
예 : 로깅
finally
블록 안에 물건을 기록하고 싶다고 가정 해 봅시다 . 로깅이 실패 하지 않는 한 이것은 종종 큰 문제가 될 것 입니다. 파일에 더 많은 데이터를 추가 할 수 있기 때문에 거의 확실하게 로깅에 실패 할 수 있으며 실패 할 여러 가지 이유를 쉽게 찾을 수 있습니다.
따라서 여기서 해결책은 finally
블록에 사용되는 로깅 기능 이 호출자에게 던질 수 없도록 만드는 것입니다 (실패 할 수는 있지만 던지지는 않습니다). 우리는 어떻게 할 수 있습니까? 중첩 된 try / catch 블록이있는 경우 최종 언어 내에서 언어를 던질 수있는 경우 예외를 삼키고 예외를 오류 코드로 전환하여 호출자를 던지는 것을 방지 할 수 있습니다. 기존 오류 복구 스택 외부에서 분리되어 실패 할 수있는 프로세스 또는 스레드가 풀립니다. 오류가 발생할 가능성없이 해당 프로세스와 통신 할 수있는 한, 동일한 스레드 내에서 재귀 적으로 발생하는 경우 안전 문제가이 시나리오에만 존재하므로 예외적으로 안전 합니다..
이 경우, 로그에 실패하고 아무것도하지 않는 것만으로도 실패하지 않으면 로깅 실패를 피할 수 있습니다 (예 : 리소스가 유출되거나 부작용을 롤백하지 않는 등).
어쨌든 소프트웨어 예외를 진정으로 만드는 것이 얼마나 어려운지 이미 상상할 수 있습니다. 가장 미션 크리티컬 한 소프트웨어를 제외하고는이를 최대한 활용하지 않아도됩니다. 그러나 매우 일반적인 라이브러리 작성자조차도 종종 여기에서 혼란스러워 라이브러리를 사용하여 응용 프로그램의 전체 예외 안전을 망칠 수 있기 때문에 예외 안전을 실제로 달성하는 방법에 주목할 가치가 있습니다.
SomeFileWriter
SomeFileWriter
inside을 던질 수 있다면 close
기존 예외에서 복구하는 컨텍스트에서 닫지 않는 한 일반적으로 예외 처리와 호환되지 않는다고 말하고 싶습니다. 코드가 통제 할 수없는 경우 SOL 일 수 있지만이 명백한 예외 안전 문제에 대해 작성자에게 알리는 것이 좋습니다. 그것이 당신의 통제 안에 있다면, 나의 주요 권장 사항은 그것을 닫는 것이 필요한 수단으로 실패하지 않도록하는 것입니다.
운영 체제가 실제로 파일을 닫지 못할 수 있다고 상상해보십시오. 이제 시스템 종료시 파일을 닫으려고하는 모든 프로그램이 종료 되지 않습니다 . 지금해야 할 일은 응용 프로그램을 열어 둔 상태로 유지하고 (아마 아니오) 파일 리소스를 유출하고 문제를 무시하는 것입니다 (중요하지 않은 경우에는 괜찮을 수 있음)? 가장 안전한 디자인 : 파일을 닫을 수 없도록합니다.