본문 바로가기
내일배움캠프(Sparta)/Spring

[Spring] SpringBoot의 JPA

by mmm- 2023. 11. 7.

1) SpringBoot의 JPA

1. SpringBoot환경에서의 JPA

  • Hibernate 설정
    • show_sql, foramt_sql, use_sql comments 옵션
      • Hibernate가 DB에 요청하는 모든 SQL을 보기좋게 출력해줌
    • ddl-auto
      • create : 기존 테이블 삭제 후 다시 생성 (DROP + CREATE)
      • create-drop : create와 같으나 종료시점에 테이블 DROP
      • update : 변경된 부분만 반영
      • validate : Entity와 테이블이 정상 매핑되었는지만 확인
      • none : 아무것도 하지 않음
  • SpringBoot 환경에서는 EntityManagerFactory와 EntityManager를 자동으로 생성해줌
    • application.properties에 DB 정보를 전달해주면 이를 토대로 EntityManagerFactory가 생성됨
  • @PersistenceContext annotaion을 사용하면 자동으로 생성된 EntityManager를 주입받아 사용 가능
@PersistenceContext
EntityManager em;

2. Spring의 트랜잭션

  • Spring에서 DB의 트랜잭션 개념을 application에 적용할 수 있도록 트랜잭션 관리자를 제공
  • @Transactional annotation을 클래스나 메서드에 추가하면 쉽게 트랜잭션 개념 적용 가능
    • 메서드가 호출되면, 해당 메서드 내에서 수행되는 모든 DB 연산 내용은 하나의 트랜잭션으로 묶임
    • 해당 메서드가 정상으로 수행되면 commit, 예외발생하면 rollback
    • 클래스에 선언한 @Transactional은 해당 클래스 내부의 모든 메서드에 트랜잭션 기능 부여
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
						...
			
		@Transactional
		@Override
		public <S extends T> S save(S entity) {
		
			Assert.notNull(entity, "Entity must not be null");
		
			if (entityInformation.isNew(entity)) {
				em.persist(entity);
				return entity;
			} else {
				return em.merge(entity);
			}
		}

						...
}

@Transactional(readOnly = true)를 하게 되면 readOnly = true 옵션은 데이터를 읽기만할 때 사용하는데, save메서드에서 @Transactional이 추가되게 되면 해당 annotation이 readOnly 옵션을 덮어써 readOnly = false 옵션으로 적용됨.


3. @Transactional

  • JPA를 사용해 DB에 데이터를 저장, 수정, 삭제하려면 트랜잭션 적용이 반드시 필요
  • 읽기의 경우에는 트랜잭션 적용 필수 ❌, BUT 트랜잭션 환경이 필요한 경우도 있기 때문에 readOnly = true 옵션이 설정된 @Transactional을 적용하면 좋음.

4. 영속성 컨텍스트와 트랜잭션의 생명주기

 

  • 스프링 컨테이너 환경에서는 영속성 컨텍스트와 트랜잭션의 생명주기가 일치
  • 트랜잭션이 유지되는 동안 영속성 컨텍스트도 유지되기 때문에 영속성 컨텍스트의 기능 사용 가능
스프링은 어떻게 Service부터 Repository까지 Transaction을 유지할 수 있을까?

- 스프링은 트랜잭션을 제어할 수 있도록 트랜잭션 전파기능을 제공해 계층간에도 트랜잭션이 유지될 수 있는 것.

 

 

트랜잭션 전파

  • @Transactional에서 트랜잭션 전파 옵션 지정 가능
    • 기본 옵션 : propagation.REQUIRED
      ➡️ 부모 메서드에 트랜잭션이 존재하면 자식 메서드의 트랜잭션은 부모의 트랜잭션에 합류하게됨.