해당 글은 정확한 개념보다는 지식이 전무후무한 독자들이 가볍게 읽을 수 있는 형태로 작성되었습니다. 보다 정확하고, 깊이있는 글을 원하시는 분은 다른 글을 참고하시면 좋을 것 같습니다.
자바 스프링부트 JPA를 막 시작했다. 개념보다는 실전을 먼저 들어가서, 모르는 개념을 찾아 우선적으로 익힌 다음에 개념 강의로 더 단단한 개념을 쌓으려고 시도했다.
시작하자마자 모르는 것 투성이... 다 체크하고 개념에 대해서 조금 익혔다.
이 글은 JPA에 대한 개념이 없이 영속성 컨텍스트 및 영속성에 대한 개념을 대략적으로나마 이해하고자 하는 독자에게 추천한다.
1. 엔티티
엔티티는 데이터베이스에서도 들어보았던 용어였습니다. 쉽게 얘기하자면, 데이터베이스에 한 테이블에서 하나의 행을 의미합니다. 즉, 하나의 데이터를 나타내는 것이 엔티티라고 볼 수 있습니다.
조금 더 자세하게, 코드로 살펴봅시다. 우리가 아래와 같이 Member라는 클래스를 만들었다고 합시다.
@Entity
public class Member {
@Id
private Long id;
private String username;
private int price;
}
이렇게 @Entity라는 애노테이션과 함께 필드를 생성해주면, 해당 클래스를 토대로 아래와 같은 데이터베이스가 생성되게 됩니다.
그렇게 id 필드 위에 @Id 라는 어노테이션을 확인하신 분들은 궁금해하실 수도 있습니다. 쉽게 생각하면, 우리는 보통 데이터베이스에 ID라는 값을 할당해주어, PK(Primary Key)로 설정합니다.
PK가 무엇인지 모르신다면 간단하게, 해당 row를 유일하게 해주는, 그러니까 데이터베이스에서 유일한 값을 나타내주는(row를 식별할 수 있는) 값이라고 생각합시다.
따라서 우리는 해당 클래스에 객체를 생성함으로써, 데이터베이스에 하나의 값을 만들었다고 이해하시면 조금 더 편합니다!!
2. 영속성(Persist)
단순히 단어만 들으면 굉장히 어려운 의미로 다가옵니다.(저 또한 그랬읍니다....) 하지만 정말 간단한 개념입니다. 쉽게 생각하면 영속성은
임시 데이터베이스 라고 생각하시면 됩니다.
이를 위해선 @Transactional도 이해하는 것이 좋겠네요.
우리의 DB 값은 굉장히 중요합니다. 인터넷 뱅킹만 생각해봐도, 단지 제 통장에 찍혀있는 잔고는 데이터베이스의 값을 말합니다. 만약 누가임의로 조작하거나, 실수로 값을 바꾼다면? 그건 엄청난 문제일테죠.
따라서 우리는 이 데이터베이스를 수정하는 과정(흔히들 CRUD라고도 하죠)에 대해서는 신중해야합니다.
이러한 상황을 가정해봅시다.
A는 B에게 3,000,000원을 입금해야합니다. 이를 위해서 deposit()이라는 메서드를 생각해봅시다. 간단하게 작성해보면
void deposit(Member A, Member B, int price){ // A가 B에게 price를 입금
int beforePriceA = A.getPrice();
A.setPrice(beforePriceA - price);
int beforePriceB = B.getPrice();
B.setPrice(beforePriceB + price);
}
이런 식으로 작성될 수 있습니다. 이 메서드를 통해서 A에는 3,000,000원이 빠지고, B에는 3,000,000원이 입금되겠죠. 이는 DB에도 똑같이 반영될 것입니다.
그런데 만약, 이 A와 B가 사용하고 있는 은행이 같은 은행이라고 가정하고 이 은행은 개인당 최대 5,000,000원만 가지고 있을 수 있다는 제한조건이 있다고 해봅시다.(그런 은행이 어디있겠냐만은..)
여기서 B가 원래 3,000,000원을 가지고 있었고, A에게 3,000,000원을 받는다면 이 은행이 수용할 수 있는 금액을 초과하므로, 중간에 에러를 발생시키고 이 메서드를 종료했다고 해봅시다.
이렇게 되면 어떠한 결과를 초래할까요??
A에게는 3,000,000원이 빠지게 된 셈이고, B에게는 3,000,000원이 들어오지 않았으므로 굉장히 어려운 상황이 발생했습니다. 그렇다면 이러한 것을 어떻게 해결할까요?? 아니, 이걸 왜 얘기했을까요??
여기서 나오는 개념이 영속성과 @Transactional입니다. 기본적으로 우리는 DB에 접근하여 수정하고자 하는 행동을 취한다면, 우리는 DB 자체를 수정하는 것이 아닌, DB의 수정하는 부분을 그대로 복사해와서 영속성 컨텍스트에 저장합니다.(정확히는 1차 캐시에 저장합니다!)
그런 후에, 수정이나 삭제 연산을 수행하게 됩니다. 따라서 우리는 만약에 위와 같은 오류가 메서드 중간에서 터진다면, 영속성 컨텍스트에 있는 내용들을 DB에 반영하지 않고, 종료합니다. 이렇게 되면 DB에는 값을 변경하지 않을 수 있게 되는 것이죠.
위와 같은 형태로 우리는 1차 캐시에 정보를 저장하게 됩니다!!!
만약 오류없이 메서드가 종료되었다면, 1차 캐시에 있는 값을 DB에 반영하게 됩니다.
간단하게 영속성의 개념에 대해서 알아봤습니다!!!
'JPA' 카테고리의 다른 글
[JPA] 복합키 등록하기 (0) | 2023.08.18 |
---|---|
@Transactional의 선언 위치 (0) | 2023.08.17 |
DTO, DAO란? (DAO와 Repository의 차이) (0) | 2023.08.10 |
임베디드 타입(Embedded Type)이란? (0) | 2023.08.08 |
JPA에서 Enum 타입 사용하기 (0) | 2023.08.04 |