🥕
TIL
  • [TIL] Studying tech / computer science knowledge
  • KeyMap
  • 알고리즘
    • 복잡도 계산 ( Computational Complexity )
    • DisjointSet-unionFind
    • Bellman-ford Algorithm
    • Dijkstra's Algorithm
    • DP ( Dynamic Programming , 동적 계획법 )
    • 플로이드-워셜 알고리즘 (Floyd-Warshall algorithm)
    • Kruskal's Algorithm
    • 최장 증가 수열 (Longes Increasing Subsequence)
    • Prim's Algorithm
    • 정렬
    • 시간복잡도 와 공간복잡도 ( Time Complexity & Space Complexity )
    • Topological Sort (위상 정렬)
  • 책 읽고난 후 요약
    • 프로그래밍 대회에서 배우는 알고리즘 문제해결 전략
    • cleancode
    • 도메인 주도 설계로 시작하는 마이크로서비스 개발
    • 오브젝트
  • CDC
    • debzium
    • kafka
  • 개발 상식
    • asciidoctor
    • 컴파일러
    • ELK 스택
    • 엔디안
    • git
    • Gitmoji
    • 테스트 종류
    • 라이브러리와 프레임워크
    • 정규 표현식
    • REST API
    • 동기와 비동기 / Blocking과 NonBlocking
    • Transaction Script와 Domain Model
    • 디자인 패턴
      • 행동 패턴
      • 객체 생성 패턴
        • 추상 팩토리 패턴
        • 빌더 패턴
        • 팩토리 메서드 패턴
        • [생성 패턴] 프로토 타입 (Prototype Parttern)
        • 싱글톤
      • 구조 패턴
        • 어댑터 패턴
        • 브릿지 패턴
        • 컴포짓(Composite) 패턴
        • 데코레이터
        • 프록시
    • refactoring
      • 중복 코드
      • 전역 데이터
      • 긴 함수
      • 긴 매개변수 목록
      • 가변 데이터
      • 이해하기 힘든 이름
  • 자료구조
    • AVL Tree
    • Splay Tree
    • aaTree
    • array-list
    • 자료구조 시간/공간 복잡도
    • 그래프
    • 힙
    • Red Black Tree
    • stack-queue
    • 트리 ( Tree )
  • DevOps
    • MSA
    • Kubernetes
      • AccessingAPI
      • controller
      • dashboard
      • kubernetes
      • object
      • pod
      • service
      • volume
  • Java
    • 어노테이션
    • 제어문
    • 데이터 타입
    • Enum
    • jvm
    • 연산자
    • thread
    • Java8
      • CompletableFuture
      • Date/Time
      • 어노테이션과 메타스페이스
      • 인터페이스
      • 람다식
      • Optional
      • 스트림
  • JavaScript
    • moduleProject
    • webpack-babel
    • 코어 자바스크립트
      • array
      • 함수 바인딩
      • 데코레이터와 포워딩
      • Class
      • 비교 연산자
      • Date 내장 객체
      • destructuring-assignment
      • function
      • 함수의 prototype 프로퍼티
      • 가비지 컬렉션 ( Garbage Collection )
      • JSON (JavaScript Object Notation)
      • map-set
      • 내장 프로토타입
      • new연산자와 생성자 함수
      • 객체
      • Object.keys, values, entries
      • 옵셔널 체이닝 '?.'
      • 프로퍼티 플래그
      • 프로퍼티 종류
      • 프로토 타입
      • 호출 스케줄링 ( scheduling a call )
      • scope
      • this
      • type-conversions
      • type
      • 함수의 자료형
      • var_let_const
  • Linux
    • 기본 명령어
    • 파일 종류
    • 리눅스
  • 네트워크
    • 응용 계층 ( Application Layer )
    • 오류 검출과 오류 정정
    • Http
    • Http Header
    • 컴퓨터 네트워크란
    • 네트워크 계층
    • 네트워크 제어 영역
    • 전송 계층 ( Transport Layer )
  • PHP
    • Facade
    • composer
    • scopeResolutionOperator
    • Laravel
      • SocialProvider
      • architecture
      • blade
      • controller
      • db
      • dbArchitecture
      • debug
      • eloquent
      • email
      • event
      • exceptionHandling
      • middleware
      • model
      • modelFactory
      • pagingLoading
      • queryBuilder
      • route
      • scout
      • seeding
      • tntsearch
      • validate
      • view
  • React
    • Next.js
    • React 란?
  • Spring
    • Controller
    • 요청이 들어왔을때 스프링이 처리하는 방법 ( 내부구조 )
    • ConfigurationProperties
    • Entity / DTO / VO
    • Maven
    • Repository와 DAO
    • 스프링 빈
    • Spring Framework
    • MVC 패턴
    • 도메인 입력값 검증
    • Spring Cloud
      • Spring Cloud
      • Eureka
    • Spring Data
      • JPA
      • JPA 어노테이션
      • 엔티티 비교
      • 복합 키와 식별 관계 매핑
      • JPA 예외처리
      • 객체지향 쿼리
      • EntityManagerFactory와 EntityManager
      • JPA 최적화
      • 프록시와 연관관계 맵핑
      • 연관관계
      • 상속관계 맵핑
      • 트랜잭션 범위와 영속성 컨텍스트
      • 데이터 타입
      • MySQL 연결
      • Pageable
    • Spring Project들과 library
      • Custom Serialize
      • Elasticsearch Index API
      • Spring HATEOAS
      • lombok (롬복)
      • Model Mapper
      • Object Mapper
      • Representation Model
      • Spring REST Docs
      • Spring Boot
    • Spring Security
      • Spring Security
      • Authentication
      • Authentication Filter
      • Authorization Filter
      • Filter Chain
      • SecurityContext
      • Spring OAuth2.0
    • Spring Test
      • AssertJ
      • Junit5
      • JunitParams
      • Mock Object
  • DataBase
    • ALIAS
    • CONCAT
    • CTE
    • Group By
    • HAVING
    • IFNULL
    • 인덱스
    • JOIN
    • ORDER BY
    • ROLLUP
    • SELECT
    • SELECT DISTINCT
    • SQL
    • WHERE
  • Web 상식
    • OAuth
    • WAS
    • HTTP통신 기반 인증
    • 브라우저
    • CSR 과 SSR
    • HTTPS
    • Web
Powered by GitBook
On this page
  • 해결방법
  • OSIV
  • 스프링 OSIV
  • Reference
  1. Spring
  2. Spring Data

트랜잭션 범위와 영속성 컨텍스트

스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트를 제공하는데 이는 트랜잭션 범위내에서 영속성 컨텍스트가 존재한다는 의미이다.

보통 비즈니스로직을 시작하는 Service단 부터 @Transaction어노테이션을 이용해 트랜잭션을 시작하고 이렇게 트랜잭션 범위내애서만 영속성 컨텍스타가 유지된다. (트랜잭션 어노테이션이 있으면 트랜잭션AOP가 Service의 메서드를 실행시키기전에 먼저 동작하여 트랜잭션을 시작하고 메서드가 종료되면 트랜잭션을 커밋하면서 종료한다.)

같은 트랜잭션이면 같은 영속성 컨텍스트를 사용하고 트랜잭션이 다르다면 영속성 컨텍스트도 다르기 때문에 멀티스레드 상황에도 안전하다.

이처럼 영속성 컨텍스트는 트랜잭션 범위내에서만 존재하기 때문에 트랜잭션이 끝난 controller단에서 변경감지를 통한 수정, 지연로딩을 통한 조회를 하려고 하면 에러가 발생한다. (이때 프록시 객체가 이미 초기화 되어있는 상태라면 조회는 가능하지만 초기화가 되어있지 않다면 초기화하기 위해 영속성컨텍스트를 이용해 조회하고 쿼리를 날리겠지만 트랜잭션범위 밖이기 때문에 영속성컨텍스트도 존재하지 않아 에러가 발생한다.)

해결방법

  1. 패치전략을 즉시 로딩으로 수정 : 이는 사용하지 않는 엔티티일경우에도 조회하고 N+1문제가 발생할 수 있어 성능상에 문제가 생길 수 있다.

    N+1?

    연관된 엔티티를 조회할때 JPQL을 이용해서 조회를 한다면 글로벌 패치 전략을 참조하지 않고 JPQL자체만을 해석해서 SQL문을 생성하기 때문에 JOIN을 하지 않고 연관된 테이블을 하나하나 조회하는 문제

  2. JPQL 패치 조인

    em.createQuery("select o from Order o join fetch o.memeber", Order.class).getResultList();

    위와 같이 JPQL을 fetch join으로 명시해서 SQL의 join을 이용한 조회를 사용하도록 하는 방법

    문제점 : 이렇게 view가 원하는 대로 응답을 맞추는 것은 데이터접근 계층이 view단을 의존하게 되고 그때마다 비슷한 메서드를 만드는 것은 비효율적이다.

    연관된 테이블의 정보가 필요없는 view의 요청에서도 하나의 메서드를 만들고 내부에서 무조건 즉시로딩을 한 Entity를 반환하는 방식으로 하는 것이 조금 성능면에서는 떨어질 수 있어도 조금 더 결합도를 낮출 수 있다.
  3. 강제 초기화

    지연로딩이 글로벌 페치 전략일때 view가 연관entity정보도 필요하다면 service단에서 강제로 프록시객체를 초기화하여 넘겨주는 방법

    이도 결국 view가 service계층영역을 침범하는 일이다.

    • FACADE : 계층간 역할 구분을 확실히 하기 위해 중간에 FACADE계층을 추가할 수 는 있지만 관리해야하는 계층이 한개더 추가되는 것이고 단순히 service를 호출하는 코드가 반복되게 되는데 기능하나 추가하는데 작업해야하는 코드가 많이 늘어난다.

OSIV

Open Session In View의 약자로 해석 그대로 영속성 컨텍스트의 생존 범위를 View까지 유지하는 것이다.

하지만 이는 Update와 같은 비즈니스 로직을 수행할때마다 변경내용이 DB에 반영되게 되어 유지보수가 상당히 힘들어진다. 그래서 DTO와 같은 객체를 이용해서 작업하는 방식이 있지만 애초에 많은 문제를 야기할 수 있기 때문에 사용은 되지않고 문제점을 해결한 스프링 프레임워크가 제공하느 OSIV가 있다.

  • hiberante OSIV servlet filter : OpenSessionInViewFilter

  • hibernate OSIV spring intercepter : OpenSessionInViewInterceptor

  • JPA OEIV servlet filter : OpenEntityManagerInViewFilter

  • JPA OEIV spring interceptor : OpenEntityManagerInViewInterceptor

서블릿 필터에 적용할지 인터셉터에 적용할지에 따라 위의 클래스 중 선택하여 등록을 하면 된다.

스프링 OSIV

스프링 OSIV는 일반 OSIV의 문제점을 해결하고자 나온것으로 영속성 컨텍스트는 view까지 살아있으나 트랜잭션이 시작되기전에는 읽기만 가능하고 트랜잭션 시작 범위부터 수정이 가능하다.

여기서 트랜잭션 시작 범위부터 수정이 가능하다는 것은 영속성 컨텍스트의 변경사항을 flush한다는 뜻이고 트랜잭션 범위 밖이라면 메서드가 끝나도 자동으로 flush가 수행되지도 않고 강제로 호출한다고 해도 에러가 발생한다. 하지만, 영속성 컨텍스트에 존재하는 객체는 수정이 되어있는 상태이기 때문에 수정을하고 다시 Service의 메서드를 호출해서 트랜잭션 시작범위로 들어가게 되면 영속성컨텍스트가 기존과 변경되었기 때문에 변경사항의 쿼리가 발생하는 문제가 발생한다.

때문에, controller에서는 비즈니스로직이 모두 끝나고 수정을 해야 문제가 발생하지 않는다.


Reference

자바 ORM 표준 JPA 프로그래밍 책 (김영한 저)

Previous상속관계 맵핑Next데이터 타입

Last updated 3 years ago