패스트캠퍼스 챌린지

패스트캠퍼스 환급 챌린지 13일차 : 9개 도메인 프로젝트로 끝내는 백엔드 웹 개발 (Java/Spring) 초격차 패키지 Online 강의 후기

ssoonearth 2025. 4. 13. 23:02

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

https://abit.ly/lisbva

 

 

 

 

패스트캠퍼스의 '9개 도메인 프로젝트로 끝내는 백엔드 웹 개발 (Java/Spring) 초격차 패키지 Online' 강의 수강 13일차!
오늘은 커뮤니티 피드 서비스에 Spring을 적용시키는 실습과 JPA와 영속성 컨텍스트의 기본 개념을 학습하는 작업을 진행하였다.

 

 

 

영속성 컨텍스트의 특징

- 영속 상태의 객체는 반드시 ID(식별자) 값이 있다.

 

- 1차 캐시

ID를 기준으로 1차 캐시에서 엔티티 값을 반환하고, 1차 캐시에 존재하지 않는 엔티티는 DB에서 조회하여 1차 캐시에 저장 후 반환한다.

 

- 쓰기 지연

{
	EntityManager em;
	EntityTransaction tr = em.getTransaction();

	// 트랜잭션 시작
	tr.begin();

	Member member1 = new Member(1L, "Lee");
	em.persist(member1);

	Member member2 = new Member(2L, "Kim");
	em.persist(member2);

	// 트랜잭션 커밋
	tr.commit();
}

 

위 코드처럼 객체 두 개가 persist 되면 영속성 컨텍스트 내의 '쓰기 지연 SQL 장소'에 두 개의 쿼리문과, '1차 캐시'에 두 개의 엔티티가 저장된다.

이후 commit 요청을 하면 저장되었던 두 개의 SQL문이 한 번에 DB로 요청된다. (SQL문 flush)

전달된 쿼리문을 DB에서 실행시키고, 마지막으로 트랜잭션이 commit 된다.

id가 없을 때 persist를 하면 영속성 컨텍스트를 거치지 않고 바로 DB에서 쿼리문이 실행되고 id값을 가져오므로, 쓰기 지연 처리가 되지 않는다.

DB에서 id값이 자동으로 생성되는 auto increment를 엔티티 코드에 미리 설정을 해두어야 자동으로 id값을 가져오기 위해 DB에 insert문을 실행한다. 그렇지 않다면 id값 없이 영속성 컨텍스트에 저장할 수 없다는 에러를 반환하게 된다.

트랜잭션 안에서 엔티티 매니저는 쿼리문을 바로 보내지 않고 쓰기 지연 SQL 장소에 보관하고 있다가 한번에 처리하는 것을 '쓰기 지연' 이라고 하고, 이러한 특징은 데이터베이스와의 커넥션을 줄일 수 있다.

 

- 동일성 보장

같은 트랜잭션, 같은 영속성 컨텍스트 안에서 동일한 ID를 가진 엔티티는 항상 같은 인스턴스로 보장된다.

{
	EntityManager em = ...;

	User user1 = em.find(User.class, 1L);
	User user2 = em.find(User.class, 1L);

	System.out.println(user1 == user2);  // true (동일한 인스턴스)

}

 

첫 번째 find()에서 DB에서 조회한 결과를 1차 캐시에 저장하고 두 번째 find()에서는 DB가 아닌 1차 캐시에서 바로 가져오기 때문에, user1과 user2는 실제 메모리 주소까지 같은 동일 객체이다.

 

- 변경 감지

영속성 컨텍스트에 저장된 엔티티 객체의 값을 트랜잭션 도중 개발자가 직접 변경하면, 트랜잭션이 커밋될 때 JPA가 이를 감지해서 자동으로 update SQL문을 실행해준다.

JPA는 find() 메소드를 실행하면 초기 상태의 복사본인 스냅샷을 만들어 두는데, 커밋 시점에 현재 값과 스냅샷을 비교해서 바뀐 필드를 감지하고, 변경된 필드가 있다면 update 쿼리를 만들어서 실행한다.

 

 

위에서 하나 보이는 단점이 있다. JPA를 사용하려면 EntityManager 객체 생성과 메소드 호출 등을 개발자가 매번 직접 해야 하는 것이다. 하지만, Spring Data JPA를 사용하면 이러한 단점을 보완할 수 있다.

 

Spring Data JPA

: JPA를 사용하기 쉽게 만들어 놓은 스프링에서 제공하는 모듈로, 직접 Hibernate에서 구현한 EntityManager를 선언하고 쓸 필요가 없다.

 

 

 

그동안 Spring으로 개발을 하면서 쓰기 지연, 변경 감지와 같은 키워드는 자주 보았지만 그게 정확히 어떤 동작을 하고 어떤 효과가 있는지는 제대로 이해하지 못했었는데, 이번 강의를 보고 나니 몰랐던 흐름들이 눈에 보이는 느낌이다.

기능을 개발하는 것도 중요하지만, 그 이전에 각 기능들이 어떻게 구성되고 작동하는지에 대해 자세히 공부하는 것이 정말 중요하다는 걸 느낀다.