[4] 스프링 부트와 JPA 활용 (10) - 실무 필수 최적화 (OSIV)

김정욱·2021년 4월 1일
1
post-thumbnail
post-custom-banner

OSIV ?

[ 개념 ]

  • Open Session In View의 약자
  • DB커넥션에 대한 세션View까지 유지하는 것에 대한 전략
  • 기본값true
  • 부르는 명칭이 조금씩 다르지만, 관례OSIV라고 부름
    • Hibernate : OSIV(Open Session In View)
    • JPA : OEIV(Open EntityManage In View)
  • 우리는 jpa에서 적용하는 sping.jpa.open-in-view 속성에 대해 다룰 것

[ true - 기본값 ]

  • sping.jpa.open-in-view : true
  • DB 커넥션사용자의 요청끝날 때 까지 계속 유지
  • 장점
    • DB 커넥션계속 유지한다는 것은 영속성 컨텍스트생존범위확장되는 것!
      --> 그래서 연관관계 LAZY fetch 전략서비스를 벗어난 곳에서 사용 가능!
  • 단점
    • 너무 오랜시간동안 DB 커넥션을 유지하여 리소스를 사용하기 때문에 실시간 트래픽이 중요한 Application에서는 DB 커넥션모자랄 수 있음 (장애 발생)

[ false ]

  • sping.jpa.open-in-view : false
  • DB 커넥션Transaction 내부까지만 유지
    (TransactionService에서 수행되니까 Service까지만 유지되는 것)
  • 장점
    • DB 커넥션 리소스효율적인 사용
      : 트랜잭션을 종료할 때 영속성 컨텍스트를 닫으면서 DB 커넥션반환
  • 단점
    • 모든 지연로딩트랜잭션 안에서 처리
      : 지연로딩에 관한 모든 로직Service / Repository 에서 해결해야 함

[ 해결 방안 ]

  • OSIV 전략false로 둔 상태에서 복잡성을 관리하는 방법들이 존재
    1) Command와 Query를 분리
    2) Service / Repotisotry 에서 모든 지연로딩을 처리

  • CommandQuery분리하는 방법 (김영한님 선호)
    : Controller에서 지연로딩을 처리해야 할 때 Query용 Service를 만드는 것
  • OrderService
    • OrderService
      : 핵심 비즈니스 로직
    • OrderQueryService
      : 화면이나 API맞춘 서비스 (주로 읽기 전용 트랜잭션)

[ 정리 ]

  • OSIVDB 커넥션 리소스에 대한 효율적인 사용과 관련된 전략
  • OSIV 실무 조언
    • 고객 서비스의 실시간 API
      : OSIV false설정
    • ADMIN 처럼 커넥션이 많지 않은 곳
      : OSIV true 설정
  • 해결방안
    • Service / Repository에서 지연로딩처리하는 것이 너무 많아지고 복잡해지면 파일로 따로 분리

스프링 데이터 JPA 소개

  • JPA를 사용할 때 지루하게 반복되는 코드자동화
    : 여러 도메인마다 save, findById 이런것은 반복되는 경우가 많다
  • JpaRepository 라는 인터페이스를 제공하며 이것을 상속받는 것 하나로 기능 제공
    : 기본적인 CRUD기능다양한 것들이 만들어져 있음
  • findByName처럼 특정 필드에 관한 것들도 정해진 메서드 이름으로 만들면 알아서 수행
  • 개발자인터페이스만들면 된다
    --> 스프링 데이터 JPA애플리케이션 실행시점구현체를 만들어서 알아서 주입!
  • 개발 생산성의 놀라운 확장 가능
    --> 실무에서 필수적으로 사용

Query DSL 소개

[ 정보 ]

  • JPQL만으로는 힘든 동적쿼리를 사용하기 쉽게 제공하는 오픈소스 라이브러리
  • QueryDSL은 SQL(JPQL)유사하여 자바코드동적 쿼리를 편리하게 생성
  • 장점
    • 직관적인 문법
    • 컴파일 시점에 빠른 문법 오류 발견
    • 코드 자동완성
    • 코드 재사용
    • JPQL new 명령어와는 비교가 안될정도로 깔끔한 DTO조회 지원

[ 적용 ]

( build.gradle 추가 )

/* Quyery DSL */
buildscript {
	dependencies {
		classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10")
	}
}
...
/* Quyery DSL */
apply plugin: "com.ewerk.gradle.plugins.querydsl"
...
dependencies {
  /* Query DSL */
  implementation 'com.querydsl:querydsl-jpa'
  implementation 'com.querydsl:querydsl-apt'
}
...
//querydsl 추가
//def querydslDir = 'src/main/generated'
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
	library = "com.querydsl:querydsl-apt"
	jpa = true
	querydslSourcesDir = querydslDir
}
sourceSets {
	main {
		java {
			srcDirs = ['src/main/java', querydslDir]
		}
	}
}
compileQuerydsl{
	options.annotationProcessorPath = configurations.querydsl
}
configurations {
	querydsl.extendsFrom compileClasspath
}

( compile 실행 )


( 만들어진 파일 )

[ 검색기능 QueryDSL로 변경 ]

profile
Developer & PhotoGrapher
post-custom-banner

0개의 댓글