SpringDB 10

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

데이터를 DB에 저장할 때 같은 ID가 이미 데이터베이스에 저장되어 있다면, 데이터베이스는 오류 코드를 반환하고, 이 오류 코드를 받은 JDBC 드라이버는 SQLException 을 던진다. 그리고 SQLException 에는데이터베이스가 제공하는 errorCode 라는 것이 들어있다. 데이터베이스 오류 코드 그림을 보자. H2 데이터베이스의 키 중복 오류 코드 e.getErrorCode() == 23505 SQLException 내부에 들어있는 errorCode를 활용 => 데이터베이스에서 어떤 문제가 발생했는지 확인할 수 있다. H2 데이터베이스 예는 아래와 같다. 23505: 키 중복 오류 42000: SQL 문법 오류 키 중복 오류 코드(H2 데이터베이스 오류 코드는 여기를 참고 H2 DB: 2..

Spring/SpringDB 2022.06.28

체크 예외와 인터페이스 / 런타임 예외 적용

서비스 계층은 가급적 특정 구현 기술에 의존하지 않고 순수하게 유지하는 것이 좋다. MemberRepository 인터페이스를 도입해서 구현 기술을 쉽게 변경할 수 있게 해본다. 인터페이스를 도입하면 MemberService는 MemberRepository 인터페이스에만 의존하면 된다. 구현 기술을 변경하고 싶으면 DI를 사용해서 MemberService 코드의 변경 없이 구현 기술을 변경할 수 있다. MemberRepository 인터페이스 package hello.jdbc.repository; import hello.jdbc.domain.Member; public interface MemberRepository { Member save(Member member); Member findById(Stri..

Spring/SpringDB 2022.06.28

언체크 예외 활용

언체크 예외 활용(런타임 예외 활용) 런타임 예외 사용 - 그림 SQLException을 런타임 예외인 RuntimeSQLException으로 변환 ConnectException 대신 RuntimeConnectException을 사용하도록 바꿈 런타임 예외이기 때문에 서비스, 컨트롤러는 해당 예외들을 처리할 수 없으면 별도 선언 없이 그냥 두면 됨. 런타임 예외 사용 변환 - 코드 - UncheckedAppTest package hello.jdbc.exception.basic; import org.testng.annotations.Test; import java.net.ConnectException; import java.sql.SQLException; public class UnCheckedAppTes..

Spring/SpringDB 2022.06.22

체크 예외 활용

체크 예외 vs 언체크 예외 언제 사용하면 좋을까? 기본 원칙은 다음 2가지이다. 기본적으로 언체크(런타임) 예외를 사용 체크 예외는 비즈니스 로직상 의도적으로 던지는 예외에만 사용 체크 예외 예) => 계좌 이체 실패 예외 / 결제시 포인트 부족 예외 / 로그인 ID, PW 불일치 예외 100% 체크 예외로 만들어야 하는 것은 아니다. 다만 계좌 이체 실패처럼 매우 심각한 문제는 개발자가 실수로 예외를 놓치면 안된다고 판단할 수 있다. 이 경우 체크 예외로 만들어 두면 컴파일러를 통해 놓친 예외를 인지할 수 있다. 체크 예외 문제점 체크 예외는 컴파일러가 예외 누락을 체크해주기 때문에 개발자가 실수로 예외를 놓치는 것을 막아준다. 그래서 항상 명시적으로 예외를 잡아서 처리하거나, 처리할 수 없을 때는 ..

Spring/SpringDB 2022.06.22

체크 예외 기본 이해

체크 예외 예제를 만들어보자. @Test 어노테이션이 아래와 같이 나와야 하는데 import org.junit.jupiter.api.Test; 내가 지정한 어노테이션은 아래와 같다. 그래도 빌드는 잘된다. import org.testng.annotations.Test; package hello.jdbc.exception.basic; import lombok.extern.slf4j.Slf4j; import org.testng.annotations.Test; @Slf4j public class CheckedTest { @Test void checked_catch() { Service service = new Service(); service.callCatch(); } /** * Exception을 상속받은 ..

Spring/SpringDB 2022.06.20

자바 예외 계층 & 예외 기본 규칙

예외 계층의 그림은 아래와 같다. Object : 예외도 객체이다. 모든 객체의 최상위 부모는 Object 이므로 예외의 최상위 부모도 Object 이다. Throwable : 최상위 예외이다. 하위에 Exception 과 Error 가 있다 Error : 메모리 부족이나 심각한 시스템 오류와 같이 애플리케이션에서 복구 불가능한 시스템 예외이다. 애플리케이션 개발자는 이 예외를 잡으려고 해서는 안됨. 상위 예외를 catch 로 잡으면 그 하위 예외까지 함께 잡는다. 따라서 애플리케이션 로직에서는 Throwable 예외도 잡으면 안되는데, 앞서 이야기한 Error 예외도 함께 잡을 수 있기 때문에다. 애플리케이션 로직은 이런 이유로 Exception 부터 필요한 예외로 생각하고 잡으면 된다. 참고로 Err..

Spring/SpringDB 2022.06.20

트랜잭션 AOP 적용

트랜잭션 AOP를 사용하는 새로운 서비스 클래스를 만들어보자.(MemberServiceV3_3) package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; import java.sql.SQLException; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @RequiredArgsConstructor ..

Spring/SpringDB 2022.06.20

트랜잭션 AOP 이해

프록시 도입 전 프록시를 도입하기 전에 기존처럼 서비스의 로직에서 트랜잭션을 직접 시작 서비스 계층의 트랜잭션 사용 코드 예시 //트랜잭션 시작 TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition()); try { //비즈니스 로직 bizLogic(fromId, toId, money); transactionManager.commit(status); //성공시 커밋 } catch (Exception e) { transactionManager.rollback(status); //실패시 롤백 throw new IllegalStateException(e); } 프록시 도입 후 프록시 사용 시 트랜..

Spring/SpringDB 2022.06.20

트랜잭션 문제 해결 - 트랜잭션 매니저2 & 트랜잭션 탬플릿

트랜잭션 매니저의 전체 동작 흐름을 자세히 보자. 트랜잭션 매니저 1 - 트랜잭션 시작 클라이언트의 요청으로 서비스 로직을 실행 서비스 계층에서 transactionManager.getTransaction() 을 호출해서 트랜잭션을 시작한다. 트랜잭션을 시작하려면 먼저 데이터베이스 커넥션이 필요하다. 트랜잭션 매니저는 내부에서 데이터소스를 사용해서 커넥션을 생성한다. 커넥션을 수동 커밋 모드로 변경해서 실제 데이터베이스 트랜잭션을 시작한다. 커넥션을 트랜잭션 동기화 매니저에 보관한다. 트랜잭션 동기화 매니저는 쓰레드 로컬에 커넥션을 보관한다. 따라서 멀티 쓰레드 환경에 안전하게 커넥션을 보관할 수 있다. 트랜잭션 매니저2 - 로직 실행 서비스는 비즈니스 로직을 실행하면서 리포지토리의 메서드들 호출. 이 ..

Spring/SpringDB 2022.06.20

트랜잭션 추상화 & 트랜잭션 동기화

트랜잭션 추상화 인터페이스는 아래와 같다. public interface TxManager { begin(); commit(); rollback(); } 트랜잭션은 사실 단순하다. 트랜잭션을 시작하고, 비즈니스 로직의 수행이 끝나면 커밋하거나 롤백 그리고 아래와 같이 인터페이스 기반으로 각각 기술에 맞게 구현체를 만든다. JdbcTxManager: JDBC 트랜잭션 기능을 제공하는 구현체 JpaTxManager: JPA 트랜잭션 기능을 제공하는 구현체 트랜잭션 추상화와 의존관계 서비스는 특정 트랜잭션 기술에 직접 의존하는 것이 아니라, TxManager이라는 추상화된 인터페이스에 의존. 원하는 구현체를 DI를 통해서 주입하면 된다. JDBC 트랜잭션 기능이 필요하면 JdbcTxManager이라는 서비스에..

Spring/SpringDB 2022.06.20