Notice
Recent Posts
Recent Comments
Link
관리 메뉴

look-forest

숲 보기 본문

Spring/Spring 데이터 접근 - 핵심 원리

숲 보기

studyHub 2024. 11. 29. 14:04

JDBC

Java DB 연결 표준 인터페이스

DataSource : 커넥션을 얻는 표준 인터페이스

  • DriverManager : 라이브러리에 있는 드라이버를 보고 연결 try.
  • ConnectionPool : 미리 연결 획득. 커넥션 풀에 들어있는 커넥션은 DB와 연결되어 있는 상태.

트랜잭션

커넥션이 생성되면 세션이 생성되는데, 이 세션에서 트랜잭션을 수행.

 

트랜잭션은 서비스 계층에서 시작해야 한다.

같은 커넥션을 유지해야 같은 세션을 사용할 수 있다.

Connection con = dataSource.getConnection();

try {
    con.setAutoCommit(false); //트랜잭션 시작
    /*비즈니스 로직*/
    con.commit; //성공 시 커밋
} catch (Exception e) {
	con.rollback(); //실패 시 롤백
} finally {
	release(con); //커넥션 반환 시, 커넥션 풀을 고려하여 자동 모드로 변환한다.(기본이 자동모드)
}

 

순수한 서비스 계층

서비스 계층은 최대한 변경없이 유지되어야 한다. 가급적 비즈니스 로직만 구현하고 특정 구현 기술에 직접 의존해서는 안된다. 이렇게 하면 향후 구현 기술이 변경될 때 변경의 영향 범위를 최소화 할 수 있다.

 

트랜잭션 매니저 - 트랜잭션 추상화, 동기화 제공

1. 트랜잭션 추상화

서비스는 특정 기술에 직접 의존하는것이 아니므로 JDBC->JPA 변경 시 코드 변경 x

package org.springframework.transaction;

public interface PlatformTransactionManager extends TransactionManager {
	//이름이 getTransaction() 인 이유는 기존에 이미 진행중인 트랜잭션이 있는 경우 해당 트랜잭션에 참여할 수 있기 때문
	TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
	
	void commit(TransactionStatus status) throws TransactionException;
	
	void rollback(TransactionStatus status) throws TransactionException;
}

 

2. 트랜잭션 동기화

트랜잭션을 유지하려면 트랜잭션의 시작부터 끝까지 같은 커넥션을 유지해야 한다. 트랜잭션 동기화 매니저는 쓰레드 로컬을 이용해서 커넥션을 동기화해준다.

트랜잭션 동기화를 사용하려면 DataSourceUtils를 사용해야 한다

 

트랜잭션은 커밋하거나 롤백하면 종료 된다

 

트랜잭션 템플릿  - 중복 해결 

트랜잭션 사용 시 try , catch , finally 를 포함한 성공시 커밋, 실패 시 롤백 코드가 반복된다.

TransactionTemplate라는 템플릿 클래스를 사용하면 중복이 제거된다.

  • 비즈니스 로직이 정상 수행되면 커밋.
  • 언체크 예외가 발생하면 롤백. 그 외의 경우 커밋. (체크 예외의 경우에는 커밋. 관리가 되므로)
this.txTemplate = new TranctionTemplate(transcationManager);

txTemplate.executeWithoutResult((txStatus -> {
	try{
    		bizLogic();
	} catch(SQLException){    
    		throw new IllegalStateException(e);
    }
}));

 

 

트랜잭션 AOP - 순수한 서비스 계층 달성

@Transaction만 붙여주면,  스프링의 트랜잭션 AOP는 이 애노테이션을 인식해서 트랜잭션 프록시를 적용해준다.

트랜잭션 프록시가 트랜잭션 처리 로직을 모두 가져간다. 그리고 트랜잭션을 시작한 후에 실제 서비스를 대신 호출한다.

트랜잭션 AOP는 스프링 빈에 등록된 트랜잭션 매니저를 찾아서 사용하기 때문에 트랜잭션 매니저를 스프링 빈으로 등록해둬야 한다.

스프링 부트는 데이터소스와 트랜잭션 매니저를 스프링 빈에 자동으로 등록한다

  • application.properties 에 있는 속성을 사용해서 DataSource( HikariDataSource )를 생성
  • 현재 등록된 라이브러리를 보고 적절한 트랜잭션 매니저 생성

순수한 서비스 계층을 만들기 위한 예외 처리

 

SQLException 같은 체크 예외는 JDBC에 의존적이라, 다른 구현 기술로 변경하면 모든 코드를 전부 수정해야 한다.

따라서 해결할 수 없는 오류는 언체크 예외로 변환해 무시하고 컨트롤러 어드바이스 등에서 일괄 처리하는게 좋다.

 

이 때 스프링에서 추상화한 예외로 catch하면 DB별 상이한 오류코드를 외우지 않아도 되고, 변경에 용이하다.

스프링 예외 변환기는 DB별 오류 코드를 스프링에서 추상화한 예외로 자동 변환해준다.

(보통 @Repository가 적용된 클래스에서 SQL 예외를 처리할 때 Spring이 SQLExceptionTranslator를 자동으로 사용)

스프링은 데이터 접근 계층에 대한 수십 가지 예외를 정리해서 일관된 예외 계층을 제공한다

'Spring > Spring 데이터 접근 - 핵심 원리' 카테고리의 다른 글

요약  (0) 2024.08.30
스프링과 문제 해결 - 예외 처리, 반복  (0) 2024.08.16
자바 예외 이해  (0) 2024.08.15
스프링과 문제 해결 - 트랜잭션  (0) 2024.08.13
트랜잭션 이해  (0) 2024.08.12