본문 바로가기
성과/수강이력

스프링 DB 1편 - 데이터 접근 핵심 원리

by POWER_ESFJ 2024. 4. 29.

JDBC 이해

애플리케이션 서버 ↔ DB 서버

  1. 커넥션 연결 : Connection
  2. SQL 전달 : Statement
  3. 결과 응답 : ResultSet

DB 마다 다른 스펙을 가진다.

⇒ JDBC (표준 인터페이스) 등장

: Java Database Connectivity

 

DB 벤더마다 JDBC Driver(JDBC 인터페이스를 구현한 라이브러리) 를 제공한다

Mapper : JdbcTemplate, MyBatis

 

ORM 기술: 객체를 관계형 데이터베이스 테이블과 매핑해주는 기술

대표기술: JPA(인터페이스) ( ⇒ JPA 를 구현한 것이 하이버네이트, 이클립스 링크)

 

SQL Mapper VS ORM

⇒ SQL Mapper 는 SQL 만 작성할줄 알면 금방 배워서 사용 가능

⇒ ORM 은 SQL 을 직접 작성하지 않아도 되어서 개발 생산성이 매우 높아진다. 편리한 반면에 쉬운 기술이 아니므로 실무에서 사용하려면 깊이있게 학습해야 한다.

커넥션풀과 데이터소스

커넥션을 맺는데 비용이 많이듬

 

쓰레드풀과 같이 커넥션풀을 만들어서 미리 커넥션을 맺어놓고 애플리케이션에서 꺼내쓰자

 

커넥션을 획득하는 방법을 추상화하는 인터페이스 ⇒ DataSource

 

DataSource 라는 인터페이스를 구현한게 HikariCP 커넥션 풀,,,

JDBC 도 커넥션풀을 쓸 수 있게 DriverManagerDataSource 라는 DataSource를 구현한 클래스를 제공

 

트랜잭션 이해

데이터를 저장할 때 파일에 저장하지 않는 이유

⇒ 데이터베이스는 트랜잭션을 지원하기 때문

 

ACID 를 보장

원자성(A): 모두 성공하거나 모두 실패

일관성(C): 일관성 있는 데이터베이스 상태 유지(ex: 무결성 제약 조건을 항상 만족)

격리성(I) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리 (성능이슈로 격리 수준을 선택할 수 있다)

지속성: 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제가 발생해도 데이터베이스 로그등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.

 

격리성을 완벽하게 보장하려면 트랜잭션을 거의 순서대로 실행해야 한다.

트랜잭션 격리 수준 - isolation level

(밑으로 갈수록 느려짐, DB 마다 조금씩 다름)

  • READ UNCOMMITED (커밋되지 않은 읽기) ⇒ 성능은 가장 좋으나 데이터 정합성 보장 안됨
  • READ COMMITED(커밋된 읽기) ⇒ 가장 많이 사용함
  • REPEATABLE READ(반복 가능한 읽기) ⇒ 또는 이 옵션
  • SERIALIZABLE (직렬화 가능)

데이터베이스 연결 구조와 DB 세션

  • 사용자에서 커넥션을 맺으면 DB 서버 내부에서는 세션이 생성된다
  • 커넥션 풀이 10개 만들어지면 세션이 10개 만들어진다.
  • 세션은 사용자가 커넥션을 끊거나 DBA(DB관리자)가 세션을 강제 종료하면 세션은 종료된다.

트랜잭션을 유지하려면 같은 세션안에서 실행되어야 한다 ⇒ 같은 커넥션을 써서 실행을 해야 트랜잭션이 유지된다

 

자바 예외 이해

 

체크 예외의 장단점

  • 장점: 개발자가 실수로 예외를 누락하지 않도록 컴파일러를 통해 문제를 잡아주는 훌륭한 안전장치이다.
  • 단점: 너무 번거롭다. 의존관계에 따른 단점이 존재

언체크 예외

  • RuntimeException 과 그 하위 예외는 언체크 예외로 분류된다.
  • 컴파일러가 예외를 체크하지 않는다는 뜻이다
  • thorws 를 선언하지 않고 생략할 수 있다.
  • 장점: 신경쓰고 싶지 않은 uncheck 예외를 모두 무시할 수 있다
  • 단점: 개발자가 실수로 예외를 누락할 수 있다.

정리

  • check 예외와 uncheck 예외의 차이는 예외를 처리할 수 없을 때 예외를 밖으로 던지는 부분에 있다(throws). 이부분을 필수로 선언해야 하는가 생략할 수 있는가의 차이다.

체크 예외 활용

  • 기본적으로 언체크(런타임) 예외를 사용하자
  • 체크 예외는 비지니스 로직상 의도적으로 던지는 예외에만 사용하자
    • 계좌 이체 실패 예외
    • 결제시 포인트 부족 예외
    • 로그인 ID, PW 불일치 예

1. 복구 불가능한 예외

대부분의 예외는 복구가 불가능하다

SQLException 같은 경우에는 App 에서 복구가 불가능하다. DB 서버가 다운 되었거나 하는 경우

해당 오류의 경우 개발자가 해당 오류를 빠르게 인지하는게 필요하다.

서블릿 필터, 스프링 인터셉터, 스프링의 ControllerAdvice 를 사용하면 이런 부분을 깔끔하게 공통으로 해결할 수 있다.

2. 의존 관계에 대한 문제

본인이 해결이 불가능해도 어쩔 수 없이 throws 를 통해 던지는 예외를 선언해야 한다.

Service 나 Controller 에서 SQLException 에 의존하게 되면, JDBC 에서 JPA 로 변경하게 되면 JPA에 해당하는 Exception 에 의존하도록 변경해야 한다.

그렇다고 throws Exception 으로 바꿔버리면 check Exception 을 던지는 의미가 퇴색된다.

예외 포함과 스택 트레이스

            try {
                runSQL();
            } catch (SQLException e) {
                // checked 예외를 unChecked 예외로 변환해서 반환한다
                throw new RuntimeSQLException(e);
            }
20:58:07.207 [main] INFO  h.j.exception.basic.UnCheckedAppTest -- ex
hello.jdbc.exception.basic.UnCheckedAppTest$RuntimeSQLException: java.sql.SQLException: ex
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
**Caused by: java.sql.SQLException: ex**
	at hello.jdbc.exception.basic.UnCheckedAppTest$Repository.runSQL(UnCheckedAppTest.java:65)
	at hello.jdbc.exception.basic.UnCheckedAppTest$Repository.call(UnCheckedAppTest.java:57)
	... 73 common frames omitted
	          try {
                runSQL();
            } catch (SQLException e) {
                // checked 예외를 unChecked 예외로 변환해서 반환한다
                throw new RuntimeSQLException(); // 빼먹으면 기존 Error 가 안 나온다
                // 오류 발생 원인 **SQLException** 추적 불가
            }

20:59:29.349 [main] INFO  h.j.exception.basic.UnCheckedAppTest -- ex
hello.jdbc.exception.basic.UnCheckedAppTest$RuntimeSQLException: null
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)

Process finished with exit code 0

 

 

DEVSI30/inflean-spring-db-1-jdbc: 인프런 스프링 DB 1 / JDBC 이해 (github.com)

 

GitHub - DEVSI30/inflean-spring-db-1-jdbc: 인프런 스프링 DB 1 / JDBC 이해

인프런 스프링 DB 1 / JDBC 이해. Contribute to DEVSI30/inflean-spring-db-1-jdbc development by creating an account on GitHub.

github.com