[Spring] 스프링 DAO와 JDBC 템플릿 및 트랜잭션 관리

Jiwoo Jung·2024년 11월 22일
0

GDGoC Spring 스터디

목록 보기
11/15

GDG on Campus Backend-Spring 스터디 WIL
Week 06 - 스프링 DAO와 JDBC 템플릿 및 트랜잭션 관리


스프링 DAO

Data Access Object(데이터 접근 객체)

실제로 데이터베이스에 접근하는 객체
서비스와 데이터베이스를 연결하는 역할을 하며, 실제로 DB에 접근하여 데이터 CRUD 작업(삽입, 삭제, 조회, 수정)을 수행한다.

  • 캡슐화
    DAO는 데이터베이스 작업을 추상화하고 캡슐화하여 데이터 소스 접근과 비즈니스 로직을 분리한다.
  • 재사용성
    DAO 패턴은 코드의 재사용을 도와준다. 다양한 데이터 소스에 대해 일관된 인터페이스를 제공한다.
  • 유지보수성
    데이터 접근 로직에 한 곳에 모여 있어 유지보수에 유리하다. 변경사항을 쉽게 적용할 수 있다.

스프링 DAO의 필요성

  • 코드 간소화
    반복적인 JDBC 코드 간소화. 개발자는 비즈니스 로직에 집중 가능
  • 예외처리 개선
    checked 예외를 unchecked 예외로 변환하여 예외 처리의 유연성을 높인다.
  • 테스트 용이성
    의존성 주입을 통해 DAO를 쉽게 모의 객체로 대체할 수 있다. 이는 단위테스트를 용이하게 한다.

Chcked, Unchocked Exception

Checked exception: RuntimeException의 하위 클래스가 아니면서 Exception 클래스의 하위 클래스들. 반드시 에러 처리를 해야 한다.
Unchecked exception: RuntimeException의 하위 클래스들. 실행 중에(runtime) 발생할 수 있는 예외를 의미. 에러 처리를 강제하지 않는다.


JDBC 템플릿

  • 템플릿 메서드 패턴
    JDBC 템플릿은 템플릿 메서드 패턴을 구현하여 반복적인 코드를 추상화한다.
  • 콜백 사용
    RowMapper, ResultSetExtractor 등의 콜백을 통해 결과 매핑을 커스터마이즈할 수 있다.
  • 배치 작업 지원
    batchUpdate 메서드로 대량 데이터 처리를 효율적으로 처리한다.

템플릿 메서드 패턴

메소드의 구조를 정의하고, 일부 단계를 하위 클래스에서 구현하도록 하는 디자인 패턴. 이를 통해 메소드의 구조 변경 없이 특정 단계를 재정의할 수 있다. 이는 반복적인 코드를 효과적으로 추상화하고 재사용성을 높이는데 도움이 된다.

JDBC 템플릿 관련 의존성

  • spring-jdbc
    JDBC 및 데이터소스 지원을 위한 핵심 의존성. 이는 JDBC 템플릿을 사용하기 위해 필요하다.
  • spring-tx
    트랜잭션 관리를 위한 의존성. 선언적 트랜잭션 관리를 사용할 때 필요하지만, spring 4.3.3 버전부터 spring-txspring-jdbc에 포함.
  • 데이터베이스 드라이버
    사용하는 데이터베이스에 맞는 JDBC 드라이버를 추가. (MySQL을 사용한다면 mysql-connector-java 추가)

JDBC 템플릿 사용법

  1. 의존성 추가
  2. DataSource 설정
    데이터베이스 연결 정보를 포함한 DataSource를 구성한다.
  3. JdbcTemplate 생성
    DataSource를 이용해 JdbcTemplate 객체를 생성한다.

데이터베이스 설정 - DataSource

  1. DataSource 빈 정의
    xml 또는 java 설정으로 DataSource 빈을 정의한다. 이는 데이터베이스 연결 정보를 포함한다.
  2. Connection Pool 설정
    HikariCP와 같은 연결 풀을 사용하여 성능을 최적화하여 데이터베이스 연결을 효율적으로 관리한다.
  3. property 외부화
    데이터베이스 연결 정보를 properties 파일로 분리한다.

JDBC 사용시 문제점

  1. 자원 관리 부담
    Connection, Statement, ResultSet 등의 자원을 수동으로 관리해야 한다. 이는 메모리 낭비의 위험이 있더,
  2. 예외 처리 복잡성
    JDBC의 checked 예외는 처리가 번거롭다. 이는 코드를 복잡하게 만든다.
  3. 코드 중복
    연결, 명령문 생성, 결과 처리 등의 코드가 반복되기 때문에 코드의 가독성을 떨어뜨린다.

JDBC 템플릿 장점

  1. 자원 관리 자동화
    JDBC 템플릿이 연결 열기와 닫기를 관리.
  2. 예외 변환
    JDBC 예외를 스프링의 DataAccessException으로 변환한다. 이는 예외 처리를 일관되게 만든다.
  3. 코드 간소화
    반복적인 코드를 제거하여 핵심 로직에 집중할 수 있다.

JPA와 JDBC

JPA(Java Persistent API)

객체 지향 데이터 모델링 및 영속성 관리를 제공하는 표준 API. 복잡한 SQL 쿼리 작성을 자동화하고 객체지향적 프로그래밍 방식을 지원한다.

JDBC(Java Database Connectivity)

데이터베이스와 직접 통신하는 Java API. SQL 쿼리를 직접 작성하고 실행해야 하며, 개발자가 데이터베이스 관련 코드를 직접 관리해야 한다.


트랜잭션

ACID

트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질.

Atomicity(원자성)

트랜잭션의 모든 연산이 성공하거나 모두 실패해야 한다. 이는 데이터의 일관성을 유지한다.

Consistency(일관성)

트랜잭션 전후로 데이터베이스가 일관된 상태를 유지해야 한다. 이는 데이터 무결성을 보장한다.

Isolation(고립성)

동시에 실행되는 트랜잭션들이 서로 영향을 주지 않아야 한다. 이는 동시성 문제를 방지한다.

Durability(지속성)

성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영되어야 한다. 이는 데이터의 안정성을 보장한다.

트랜잭션 관리의 중요성

데이터 일관성

트랜잭션은 여러 데이터베이스 작업을 하나의 논리적 단위로 묶어 데이터의 일관성을 보장한다.

에러 복구

문제 발생 시 롤백을 통해 데이터 무결성을 유지하여 시스템의 안정성을 높인다.

동시성 제어

여러 사용자의 동시 접근을 관리하여 데이터의 정확성과 일관성을 보장한다.

선언적 트랜잭션 관리

1. 트랜잭션 관리자 설정
DataSourceTransactionManager 빈 정의. 이는 JDBC 기반 트랜잭션을 관리한다.

2. @EnableTransactionManagement
설정 클래스에 어노테이션 추가하여 선언전 트랜잭션 관리 활성화

3. @Transactional
트랜잭션이 필요한 메서드나 클래스에 @Transactional`을 붙여 해당 범위에 트랜잭션을 적용한다.

트랜잭션 전파

어떤 트랜잭션이 동작 중인 과정에서 다른 트랜잭션을 실행할 경우 어떻게 처리하는가에 대한 개념

필요성

  • 메서드 호출
    한 메서드가 다른 메서드를 부를 때, 트랜잭션이 함께 이어져서 호출된다.
  • 안전한 데이터 처리
    작업이 하나로 묶여 처리되므로, 문제가 생기면 모든 작업이 취소되어 안전하게 처리가 가능하다.
  • 쉬운 설정
    스프링에서 제공하는 기능으로 복잡한 코드 없이 간단하게 설정 가능하다.
  • 실무 활용
    여러 데이터 작업을 안전하게 처리해야할 때 유용하다.

트랜잭션 전파 속성

전파 속성
REQUIRED기존 트랜잭션이 있으면 참여하고, 없으면 새로 생성. 가장 흔히 사용되는 기본 설정.
REQUIRES_NEW항상 새로운 트랜잭션 시작. 기존 트랜잭션은 일시중단됨.
NESTED기존 트랜잭션 내에서 중첩 트랜잭션 실행. 부분적 롤백 가능.
SUPPORT트랜잭션이 있으면 참여하고, 없어도 비트랜잭션으로 실행.

에러 처리

1. 전파 설정

@Transactional의 propagation 속성으로 트랜잭션 전파 방식을 지정한다.

2. 예외 처리

트랜잭션 내에서 발생한 예외를 적절히 처리한다. RuntimeException은 기본적으로 롤백을 유발한다.

3. 롤백 규칙

rollbackFor, noRollbackFor 속성으로 롤백 규칙을 세밀하게 조절할 수 있다.

예시

CREATE 연산

  • UPDATE() 메서드 사용
    JdbcTemplate의 update()메서드로 INSERT쿼리를 실행하여 데이터를 삽입할 수 있다.
  • 파라미터 바인딩
    ? 플레이스홀더를 사용하여 악의적인 SQL Injection을 방지할 수 있다.
  • KeyHolder 사용
    자동 생성된 키 값을 얻기 위해 사용할 수 있다. 특히 KeyHolder는 새로 삽입된 데이터의 기본 키 값을 편리하게 가져올 수 있도록 도와준다.

READ 연산

  • queryForObject()
    단일 결과를 조회할 때 사용.
    RowMapper를 통해 결과를 객체로 매핑한다.
  • query()
    여러 결과를 리스트로 조회할 때 사용한다.
    복잡한 객체 매핑에 유용하다.
  • RowMapper 구현
    ResultSet의 데이터를 객체로 변환하는 로직을 정의함으로써 재사용 가능한 매핑 전략을 제공한다.

UPDATE 연산

  • update() 메서드
    CREATE 연산과 비슷하게 UPDATE 쿼리 실행에도 update()메서드를 사용한다.
  • 다중 파라미터
    여러개의 파라미터를 순서대로 전달한다. 복잡한 UPDATE문을 실행할 때 유용하다.
  • 배치 업데이트
    batchUpdate()메서드로 여러 레코드를 한번에 업데이트할 수 있다. 대량 데이터 처리 시 성능을 향상시킨다.

DELETE 연산

  • update() 사용
    DELETE쿼리도 update()메서드를 실행한다. 영향받은 행의 수를 반환받아 삭제 여부를 확인할 수 있다.
  • 조건부 삭제
    WHERE절을 사용하여 특정 조건에 맞는 데이터만 안전하게 삭제한다.
  • 예외처리
    DataAccessException을 catch하여 삭제 중 발생할 수 있는 오류를 처리한다.

0개의 댓글