작성
·
3.3K
6
안녕하세요. 강의 잘 듣고 많은걸 배우고 있습니다.
현재 강의와는 안 맞을 수 있는내용이지만.. 많은 고민이 되어 질문드립니다ㅜ
예를들어 Team이라는 테이블이 있고, name이라는 Column이 Unique Index로 설정되어 있는 상태입니다.
CrudRepository의 save 함수를 이용해 저장하고 있고 Custom Exception을 핸들링해서 "이미 저장되어 있습니다."라는 응답값을 반환하는것이 목표입니다.
현재 고민하고 있는 방법은
1. Insert 쿼리를 사용하기전에 이미 저장된 name이 있는지 Select 쿼리로 조회해 있다면 Custom Exception을 발생.
-> 팀을 생성할때마다 Select 쿼리를 발생
2.try ... catch로 DataIntegrityViolationException을 잡아 Custom Exception 발생
-> DataIntegrityViolationException이 넓은 범위의 제약조건을 포함하고 있는 것으로 알고있어서 DuplicateKey ErrorCode로 잡아서 Custom Exception을 발생시켜야하나 싶습니다..
혹시 실무에서는 위의 방법 중 하나 혹은 다른 방법을 사용해 어떤식으로 해결하는지 궁금합니다
답변 2
24
안녕하세요. jeon9435님^^
사실 저도 이런 문제가 나올 때 마다 엄청 많이 고민합니다. ㅎㅎㅎ
결론부터 말씀드리면 어떤 고민을 할때는 기준이 필요합니다. 성능, 이해하기 쉬운 도메인 코드, 동시성 문제, 등등을 함께 기준을 가지고 고려하면 좋습니다.
성능
먼저 성능 측면에서 1번이 select 쿼리를 발생시키기 때문에 성능에 영향을 줄 것 같지만, 암달의 법칙이라고 하지요. 애플리케이션 전체를 볼때 PK나 index에서 단건을 조회하는 경우 성능에 미치는 영향은 거의 미미합니다. 그리고 대부분의 애플리케이션은 조회가 많지, 이렇게 저장하는 비즈니스 로직의 호출은 상대적으로 매우 적습니다.
그래서 이 경우 성능은 크게 고려대상이 안됩니다.
이해하기 쉬운 도메인 코드
저는 1번이 더 이해하기 쉬운 도메인 코드라 생각합니다. 코드에 체크 로직이 들어가는데 이 체크 로직 자체가 이미 비즈니스를 반영하기 때문입니다. 반면에 2번은 예외를 잡아서 처리해야 하는데, 아... 이해하기도 좀 애매합니다. 그리고 DB 관련 예외가 막상 터지면 이걸 뭔가 잡아서 해결하기 보다는 그냥 웹 애플리케이션 앞쪽까지 던지고, 공통 예외로 처리하는게 더 깔끔한 경우가 많습니다.
동시성 문제
사실 여기까지 말씀드린 내용은 1번 처럼 select를 한번 더 하더라도 체크로직으로 처리하는게 좋아보지만, 1번은 동시성 이슈에서 자유롭지 않습니다. 예를들어서 같은 이름의 사용자가 동시에 insert 처리를 하면 체크로직을 둘다 통과해서 DB까지 이동하게 됩니다. 이후에 DB에서 어떤 문제가 발생하겠지요.
권장하는 방법
제가 권장하는 방법은 체크 로직을 사용하는 것입니다. 체크 로직을 사용하면 예외를 터트러던, 아니면 예외라는 값을 반환하던 간에 원하는 상황을 깔끔하게 제어할 수 있습니다. 하지만 체크 로직만으로는 동시성 문제가 해결이 안되지요. 그런데 생각해보면 이런 동시성 문제는 진짜 거의 터질일이 없습니다. 따라서 DB에서 동시성 문제가 발생하면(Unique 제약조건 위배) 따로 catch로 잡지말고, 그냥 공통 예외로 컨트롤러 끝까지 보내서 공통 예외로 처리되도록 만듭니다. 그리고 공통 예외 처리에서 고객에게는 시스템에 문제가 있습니다. 정도로 뿌리고 대신 디버깅을위해 시스템에 로그로 자세히 남기는 정도로 마무리하면 됩니다^^
도움이 되셨길 바래요.
1