데이터 접근 예외 직접 만들기

박찬우·2024년 2월 2일

스프링 DB

목록 보기
20/53

데이터 접근 예외 직접 만들기

  • SQLException 에는 데이터베이스가 제공 하는 errorCode 라는 것이 들어있다.
  • 데이터베이스에서 어떤 문제가 발생했는지 확인할 수 있다.
  • 오류 코드를 사용할 때는 데이터베이스 메뉴얼을 확인해야 한다.
  • errorCode를 확인하여 사용하려면 결구 SQLException을 사용해야 한다(의존성 발생)
  • 리포지토리에서 예외를 변경하여 던지면 된다
  • 스프링에서는 이러한 기능들을 이미 구현하여 지원해줌

예)

@Slf4j
public class ExTranslatorV1Test {
    Repository repository;
    Service service;

    @BeforeEach
    void init() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(ConnectionConst.URL, ConnectionConst.USERNAME, ConnectionConst.PASSWORD);
        repository = new Repository(dataSource);
        service  = new Service(repository);
    }

    @Test
    void duplicateKeySave() {
        service.create("m1");
        service.create("m1");
    }

    @RequiredArgsConstructor
    static class Service {
        private final Repository repository;

        public void create(String memberId) {
            try {
                repository.save(new Member(memberId, 0));
                log.info("saveId={}", memberId);
            } catch(MyDuplicateKeyException e) {
                // MyDuplicateKeyException 예외를 잡고 키 복구를 시도 후 저장
                log.info("키 중복, 복구 시도");
                String retryId = generateNewId(memberId);
                log.info("retryId={}", retryId);
                repository.save(new Member(retryId, 0));
            } catch (MyDbException e) {
                log.info("데이터 접근 계층 예외", e);
            }
        }

        private String generateNewId(String memberId) {
            return memberId + new Random().nextInt(10000);
        }
    }

    @RequiredArgsConstructor
    static class Repository {
        private final DataSource dataSource;
        public Member save(Member member) {
            String sql = "insert into member(member_id, money) values(?, ?)";
            Connection con = null;
            PreparedStatement pstmt = null;
            try {
                con = dataSource.getConnection();
                pstmt = con.prepareStatement(sql);
                pstmt.setString(1, member.getMemberId());
                pstmt.setInt(2, member.getMoney());
                pstmt.executeUpdate();
                return member;
            } catch (SQLException e) {
                // h2 db의 코드
                // 기본키 중복은 MyDuplicateKeyException으로 던진다
                if (e.getErrorCode() == 23505) {
                    throw new MyDuplicateKeyException(e);
                }
                throw new MyDbException(e);
            } finally {
                closeStatement(pstmt);
                closeConnection(con);
            }
        }
    }
}

profile
진짜 개발자가 되어보자

0개의 댓글