스프링 DB 2(김영한 강의) - 섹션 : 스프링 전파2

섹션 목적 : 실제 예제를 통해 어떻게 스프링 전파가 활용되는지 알아보자

 

1. 세팅

   (1) 요구사항 : 회원등록시, 회원 저장 및 DB에 로그를 남기는 것

   (2) 새롭게 알게된 점 

      ① JPA의 구현체인 하이버네이트가 테스트에서 테이블을 자동으로 생성

      ② 별도의 설정이 없을 경우, Test에서는 메모리 DB로 동작

      ③ 메모리 DB 생성 -> 모든 테스트 동작 -> 메모리 DB 삭제

      ④ JPA를 통해서 데이터를 변경할 경우 Transaction이 필요. 데이터 조회시 Transaction이 불필요

   (3) 구조 : memberService 안에서 memberRepository.save()와 logRepository.save() 가 동작함

 

2. memberRepo와 logRepo에는 @Transactional이 있고, memberService에는 없는 경우, 커밋 or 롤백

   (1) memberRepo에서 트랜잭션 하나 가져와서, 커밋 or 롤백하고 트랜잭션 반환.

   (2) logRepo에서 트랜잭션 하나 가져와서, 커밋 or 롤백하고 트랜잭션 반환.

   (3) 두 개의 트랜잭션은 독립적인 것이므로 서로에게 영향을 주지 않음(하나 커밋, 하나 롤백 가능)

   -> 이럴 경우 회원은 저장됐는데 로그는 저장이 되지 않는 데이터 정합성 문제 발생

   -> 따라서, 트랜잭션을 하나로 묶을 필요가 있음

 

3. 트랜잭션을 하나로 묶는 방법 첫번째 : 단일 트랜잭션

   (1) memberService에만 @Transactional을 두고, 나머지 repo에는 빼는 방법

   (2) 이렇게 하면 애초에 트랜잭션이 service에만 생성되므로, 하나의 흐름으로 동작함

   -> 그런데 이렇게 하면 repo 각각에서 트랜잭션이 필요한 요구사항이 있을 경우, 너무 많은 메소드를 따로 만들어야함.

 

4. 트랜잭션을 하나로 묶는 방법 두번째 : 트랜잭션 전파

   (1) memberService와 repo 모두 @Transactional을 사용, 기본 전파 옵션은 REQUIRED

   (2) 이렇게 하면, service에서 새로운 트랜잭션을 하나 가져옴

   (3) 이후 repo에서는 기존에 생성된 트랜잭션을 받아서 처리

 

5. 만약 logRepo에서 롤백되면?

   (1) logRepo가 예외를 던지고, 기존 트랜잭션에 rollbackOnly = true로 바꿈

   (2) memberService는 logRepo에서 예외가 발생해서 올라와서 자기도 예외가 발생했으므로, 롤백

 

6. 새로운 요구사항 : log가 저장이 안되더라도 회원은 저장시키자

   (1) 단순히 memberService가 logRepo에서 올라온 예외를 잡아서 처리하면 될까? 아니다

   (2) logRepo가 예외를 던지면서 트랜잭션에 rollbackOnly = true로 해놓았기 때문이다

   (3) 그래서 memberService가 예외를 잡아서 처리하더라도, 트랜잭션에 rollbackOnly가 true이므로 롤백하고 UnexpectedRollbackException이 발생한다

 

7. 그렇다면 어떻게? REQUIRES_NEW 전파 옵션을 이용해서, logRepo의 트랜잭션을 분리하자

   (1) logRepo의 트랜잭션 전파 옵션을 REQUIRES_NEW로 변경

   (2) logRepo에서는 기존 트랜잭션을 잠시 미뤄두고, 새로운 트랜잭션이 생성됨

   (3) logRepo는 이 트랜잭션에 커밋 or 롤백을 하고 트랜잭션 반환

   (4) memberService는 logRepo의 예외만 처리하면, 정상적으로 커밋 수행

   -> REQUIRES_NEW는 하나의 요청에 두개의 DB 커넥션을 사용하므로, 성능이 중요한 곳에서는 주의해서 사용해야


코테준비

1. 프로그래머스 - 최소 직사각형

- 간단한 수학문제


이펙티브 자바 - 아이템 1 : 생성자 대신 정적 팩터리 메서드를 고려하라

1. 클래스의 인스턴스를 얻는 전통적인 수단 -> public 생성자

 

2. 정적 팩터리 메서드란 public static Boolean valueOf(Boolean b) 와 같은 메서드

 

3. 얻을 수 있는 장점

   (1) 이름을 가질 수 있다

      : new Boolean(true) 보다 Boolean.valueOf(true)가 더 가독성이 뛰어나다

   (2) 호출할 때마다 인스턴스를 새로 생성하지 않아도 된다 

      : Boolean.valueOf(true)는 Boolean 클래스에 이미 만들어진 static 객체를 반환한다. 이렇게 되면 생성비용이 큰 객체가 자주 요청되는 상황에서 좋다. 또한, 인스턴스를 통제할 수 있다(ex. 싱글턴)

   (3) 반환 타입의 하위 타입 객체를 반환할 수 있다

      : 만약 interface에서 static 메서드로 구현체를 반환하면, 사용자는 실제 구현체가 무엇인지 알 필요가 없다. 유연하게 사용할 수 있음

   (4) 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다

      : (3)과 비슷한 뜻이라고 생각

   (5) 정적 팩토리 메소드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다

      : 무슨말인지 잘 모르겠다...

 

4. 팩토리 메소드에서 흔히 사용되는 명명 방식들(ex. from, of, valueOf, ...)


테니스

이번주 토요일에 서울시협회장배 테니스 대회 양천구 20대 대표로 나가게 돼서, 목동레인보우 클럽에서 같이 연습함

최애 파트너가 다치는 바람에ㅜㅜ 다른 아는 형님이랑 나가게 됐음

오늘 처음 맞춰봤는데, 하... 왜 하필 이 형님이랑 파트너한 경기만 지는거야ㅜㅜ 이 형님이랑 해서 이겨야되는데ㅋㅋ쿠ㅜㅜㅜㅜ

대회 때는 중요한 순간에 더 천천히 침착하게 해서, 상대가 포인트를 어렵게 따도록 해야겠다


TIL을 작성하면서 공부한 것을 한번 더 돌아볼 수 있어서 좋다.

한번 더 머릿속에 넣는 느낌도 들고, 다시 보면서 새롭게 알게되거나 더 자세히 알게되는 것도 있다.

'이펙티브 자바' 책은 아직 많이 어려운 것 같으니, 아이템 1씩 예제를 만들어가면서 해봐야겠다.

'TIL(Today I Learned)' 카테고리의 다른 글

2023.06.28  (1) 2023.06.29
2023.06.27  (1) 2023.06.27
2023.06.26  (1) 2023.06.26
2023.06.23  (0) 2023.06.23
2023.06.21  (0) 2023.06.21

+ Recent posts