2022 Masters Course/Project Course

2022 마스터즈 코스(백엔드) 83일차 회고(2022. 5. 11.) - "인프라 구축에 대한 관심"

ikjo 2022. 5. 11. 21:26

해당 글은 코드스쿼드 2022 마스터즈 코스 "Java 웹 백엔드" 과정을 수강하면서 학습한 내용 등에 대한 회고 글입니다. :)

 

수강 회고

오늘 오전에는 호눅스의 인프라 기초에 대한 마스터 클래스 강의로 진행되었다. 마스터즈 코스 과정을 수행하면서 1월~3월까지는(팀 프로젝트 과정 시작 전) 사실 서버 인프라 구축에 대한 관심이 별루 없었다. 주로 미션 과제 기능 구현이나 객체지향적으로 프로그래밍을 하는 것에 관심이 갔었기 때문이었다. 하지만 4월부터 팀 프로젝트 과정을 시작하면서부터는 본격적으로 AWS에 웹 앱을 배포하는 작업을 했어야 했기에 인프라에 대해 관심이 가기 시작했다.

 

특히, 지난 팀 프로젝트에서 반찬 주문 서비스 웹 서비스를 구현함에 있어 Nginx와 Spring boot 그리고 MySQL 등을 AWS를 통해 배포해보면서 어떻게 하면 효율적으로 운영관리(무중단 수정 배포 등)할 수 있을지에 대한 고민이 생겼었다. 이러한 생각이 들 때 즈음 이번에 호눅스의 인프라 기초에 대한 강의는 많은 영감을 받을 수 있었고 다음 미션 과제에서는 어떤 방식으로 시도를 해볼지 많은 생각을 해볼 수 있었다.

 

 

학습 회고

영속성 컨텍스트(Persistence Context)란?

JPA에서 가장 중요한 내용으로는 객체와 관계형 데이터베이스 매핑에 대한 부분과 영속성 컨텍스트에 대한 부분이 있다. 이때 영속성 컨텍스트에 대한 부분은 실제 JPA의 내부적인 동작 즉, 동작 매커니즘과 관련된 부분이다. 우선 영속성 컨텍스트의 사전적인 정의는 '엔티티를 영구 저장하는 환경'을 의미한다. 영속성 컨텍스트는 논리적인 개념으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있는데, J2SE 환경에서 엔티티 매니저와 영속성 컨텍스트는 1:1 관계이며, 엔티티 매니저 안에 영속성 컨텍스트가 존재하는 것으로 볼 수 있다.

 

영속성 컨텍스트의 특징 1️⃣ - 1차 캐시

영속성 컨텍스트 안에는 '1차 캐시'가 존재하는데, EntityManager를 통해 find()를 실행하면 1차적으로 DB에서 먼저 조회(SQL 전송)하는 게 아니라 1차 캐시에서 먼저 조회해서 데이터를 받아온다. 만일 1차 캐시에 존재하지 않는 경우에는 DB에서 조회(SQL 전송) 후 1차 캐시에 저장한 후 데이터를 받아온다. persist()를 실행해서도 마찬가지로 객체 데이터를 DB에 바로 저장하는 게 아니라 우선 1차 캐시에 저장해놓는다.

 

하지만 1차 캐시의 성능 효과는 다소 미미하다. 왜냐하면 트랜잭션이 종료될 때 영속성 컨텍스트와 1차 캐시가 모두 삭제되기 때문이다. 즉, 특정 요청을 한 사용자 즉, 하나의 트랜잭션 내에서만 공유될 뿐 전체 사용자에게는(다른 트랜잭션에서는) 1차 캐시가 공유되지 않는 것이다. 사실 1차 캐시는 성능 보다도 매커니즘에 대한 이점이 있다.

 

영속성 컨텍스트의 특징 2️⃣ - 동일성 보장

Member a = em.find(Member.class "member1");
Member b = em.find(Member.class "member1");
System.out.println(a == b); // ==을 통한 동일성 비교 시 true

 

위와 같이 동작하는(주소값이 일치하는) 이유는 1차 캐시에서 같은 객체를 조회하기 때문이다. (마치 컬렉션에서 조회하는 것처럼!!) 이를 통해 데이터 베이스가 아닌 애플리케이션 차원에서 `반복가능한 읽기(REPEATABLE READ) 등급의 트랜잭션 격리 수준` 을 제공한다.

 

영속성 컨텍스트의 특징 3️⃣ -트랜잭션을 지원하는 쓰기 지연

em.persist(memberA);
em.persist(memberB);

 

INSERT SQL을 DB에 바로 보내지 않고 영속성 컨텍스트 안에 있는 쓰기 지연 SQL 저장소에 모아 놓았다가 커밋하는 순간 DB에 INSERT SQL을 보낸다.

 

//삭제 대상 엔티티 조회 
Member memberA = em.find(Member.class, “memberA");
em.remove(memberA); // 엔티티 삭제

 

remove 시에도 마찬가지로 DELETE SQL을 쓰기 지연 SQL 저장소에 모아놓는다.

 

영속성 컨텍스트의 특징 4️⃣ - 엔티티 수정 등 변경 감지

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

 

위 코드에서 setter 이후로 별도의 처리 없이도 엔티티 데이터의 수정사항들을 모두 DB에 반영할 수 있다. 이는 마치 자바에서 컬렉션으로부터 객체를 꺼내어 수정한 이후 다시 컬렉션이 집어넣지 않는 이치와도 같다. JPA에서는 엔티티 트랜잭션의 commit()을 호출하면 영속성 컨텍스트 내부적으로 플러시(flush)가 호출되고 엔티티와 스냅샷을 비교한다. 여기서 스냅샷이란 `값을 읽어온 최초의 시점에서의 값`으로서 최초로 영속성 컨텍스트에 들어온(1차 캐시에 들어온) 상태를 저장해놓은 것이다. 만일 이 결과가 다를 경우 UPDATE SQL을 쓰기 지연 SQL 저장소에 생성하고 이후 DB에 수정사항들을 반영한다.

 

 

학습 참고자료

  • 인프런 "자바 ORM 표준 JPA 프로그래밍 - 기본편" 

 

 

좋았던 점

  • 오늘 호눅스의 공통 클래스 수업 '인프라의 기초'를 듣고 서버에 대해서 좀 더 확장적으로 생각할 수 있어서 좋았습니다. 👍

 

 

아쉬웠던 점

  • 어제 작성한 하루 일과표를 되도록 지키기 위해 노력하고는 있지만 마음만큼 '제대로 잘' 지켜지지는 않는 거 같아 아쉬웠습니다. 💦

 

 

이전 보다 개선되었던 점

  • 호눅스의 지난 데이터 베이스 관련 마스터 클래스 강의를 복습해보면서 데이터 베이스의 내부적인 동작에 대해 좀 더 이해할 수 있게 되었습니다. 🥕