인프런워밍업스터디_BE_8일차_수업내용정리

5hseok·2024년 3월 4일
0

트랜잭션이 필요한 이유

예를 들어
1. 주문기록을 저장하고
2. 포인트를 적립시키고
3. 결제 기록을 저장하는 코드가 있다고 해보자

그러면 주문 기록은 잘 저장이 됐는데, 포인트가 적립이 되지 않았다면, 결제 기록이 저장되지 않는다. 하지만, 고객은 주문 기록이 보이니까 주문이 됐는데 왜 포인트가 적립되지 않았냐고 얘기할 수 있다. 이런 상황을 피하기 위해, 한 메소드 내에서의 작업이 모든 SQL을 성공시키거나 하나라도 실패하면 모두 실패시키는 것을 트랜잭션 이라고 한다. 쪼갤 수 없는 업무의 최소 단위이기도 한다.

트랜잭션 시작하기

start transaction

트랜잭션 정상 처리하기(SQL 반영)

commit;

트랜잭션 실패 처리하기(SQL 미반영)

rollback;

우리가 원하는 것은

Service 메소드가 시작할 때 트랜잭션이 시작되고, Service 메소드 로직이 모두 정상적으로 성공하면 commit되고, Service 메소드 로직 실행 도중 문제가 생기면 rollback 되는 것이다.

스프링에서는 트랜잭션을 @Transactional을 사용해서 쉽게 적용시킬 수 있다. Service 메소드를 찾아 그위에 @Transactional을 붙인다. org.springframework.transaction에서의 Transactional 어노테이션을 붙인다. 이렇게 하면 복잡하게 start transaction, commit, rollback 등을 안해도 되고, 알아서 트랜잭션이 적용된다.
이때, SELECT 쿼리만 사용한다면, readOnly 옵션을 붙일 수 있는데, 이때는 CRUD 등에서의 데이터 변경을 위한 불필요한 기능이 빠지기 때문에 약간의 성능적 이점이 생긴다.

주의사항

@Transactional은 IOException과 같은 Checked Exception은 rollback이 일어나지 않는다.

영속성 컨텍스트

테이블과 매핑된 Entity 객체를 관리/보관하는 역할이다. 잘 감이 오지 않는다면, 이것만 기억하자. 스프링에서는 트랜잭션을 사용하면 영속성 컨텍스트가 생겨나고, 트랜잭션이 종료되면 영속성 컨텍스트가 종료된다.

영속성 컨텍스트의 특징 4가지

  1. 변경 감지
  • 영속성 컨텍스트 안에서 불러와진 Entity는 명시적으로 save하지 않아도, 변경을 감지해 자동으로 저장된다.

    이렇게 user의 이름을 업데이트하고 그 user를 다시 save하지 않아도 알아서 변경을 감지해서 업데이트가 된다.
  1. 쓰기 지연
  • DB의 INSERT, DELETE, UPDATE 등의 SQL을 바로 날리는 것이 아니라, commit될 때 다 모아서 한번만 보낸다.
  1. 1차 캐싱
  • ID를 기준으로 Entity를 기억하는 것이다.

    다음과 같은 코드에서 user1,2,3 모두 userRepository에서 Id를 1로 가지는 user를 가져와서 저장한다. 이때, user1에 Id가 1인 user를 DB에서 가져와서 저장하고, user2에 같은 user를 저장하려고 할 때, DB에서 가져오는 것이 아니라, 영속성 컨텍스트가 이 user를 기억하고 있기 때문에 DB와 통신하지 않아도 된다. 이렇게 영속성 컨텍스트가 기억하고 있는 객체는 완전히 동일하다. 이는 객체의 인스턴스 주소까지 완전히 동일하다는 것을 말한다.

0개의 댓글

관련 채용 정보