이번 포스팅에서는 ORM과 JPA에 대해 이야기해보고자 한다.
📌 ORM에 대해 알아봅시다
ORM은 Object Relational Mapping의 약어인데, 객체와 관계형 데이터베이스를 매핑한다는 의미를 가진다.
데이터베이스는 테이블로 이루어져 있고, 테이블 내에는 컬럼이 존재한다. 데이터베이스 내에 테이블과 컬럼을 정의하기 위해서는 SQL이라는 프로그래밍 언어를 활용해야 되는데, ORM을 사용함으로써 SQL을 직접 작성하지 않고 데이터베이스 내에 테이블과 컬럼을 정의할 수 있게 된다.
즉, 프로그래밍 언어로 작성된 객체가 데이터베이스의 테이블이 되고, 객체 내의 필드가 데이터베이스의 컬럼이 된다.
Java 진영에서의 ORM을 하기 위해서 사용되는 것이 JPA이다.
📌 JPA가 가지는 의미
JPA는 Java Persistence API의 약어이다. 즉, 자바의 영속성을 구현하기 위해 사용되는 것이라고 이해할 수 있다.
영속성이라는 것은 영구적으로 저장한다라는 의미를 가지는데, JPA는 Java로 작성된 객체의 상태를 영구히 저장하기 위한 API를 말하는 것이다.
JPA를 통해 자바로 프로그래밍 된 객체와 필드로 데이터베이스를 생성할 수 있고, 데이터베이스에서 이를 삭제하거나 수정하지 않으면 영구적으로 남아있게 된다.
이 밖에도 JPA에 대해 깊이 이해하기 위해서는 영속성 컨텍스트에 대해서 학습을 해야 한다.
📌 영속성 컨텍스트에 대해 알아봅시다.
영속성 컨텍스트는 JPA를 사용할 때 JPA가 객체의 상태를 관리하는 공간인데, 트랜잭션이 시작되면 컴퓨터의 메모리로부터 할당받은 메모리의 일부이다.
이러한 영속성 컨텍스트는 여러 특징을 가진다.
💡1차 캐시
JPA 메서드로 데이터베이스 내에 저장된 객체를 조회하면, 영속성 컨텍스트에 이를 등록한다. 이로써, 같은 트랜잭션 내에서 같은 객체를 조회하면 데이터베이스에서 조회를 하지 않고 영속성 컨텍스트에서 조회를 한다.
영속성 컨텍스트는 메모리이기 때문에 데이터베이스로부터 조회하는 것에 비해 성능 상 이점을 얻게 된다. 이러한 특징을 1차 캐시라고 한다.
그래서 좀 더 정확히 표현하면 JPA 메서드로 객체를 조회할 때, 영속성 컨텍스트 내 1차 캐시에 조회한 객체를 저장하는 것이다.
💡 변경 감지
변경 감지는 변경 사항을 감지해 트랜잭션이 끝날 때 자동으로 이를 데이터베이스에 반영해 주는 것을 말한다.
예를 들어, 객체의 수정을 위해 A라는 객체를 조회했다고 가정하겠다. 이때, 영속성 컨텍스트 내 1차 캐시에 해당 객체가 등록이 된다.
이후, 해당 객체에 대해서 변경 사항이 생기면, JPA는 1차 캐시에 등록된 객체와 비교하여 변경 사항에 대해서 자동으로 update 쿼리를 작성해 준다.
해당 쿼리를 트랜잭션이 끝났을 때 호출하여 데이터베이스에 반영한다. 하지만, 변경 감지에 대해서는 트랜잭션의 경계가 명확해야 이루어져야 한다. 이유는 트랜잭션의 경계가 없으면, 동시다발적으로 메서드가 호출될 시에 예상하지 못한 결과가 나올 수 있기 때문이다.
예를 들어, 현재 재고를 조회해서 +1을 하는 메서드가 있다고 할 때, 동시에 3명이 해당 메서드를 호출했다고 가정하겠다.
현재 재고는 5개였고, 3명은 동시에 호출을 했기 때문에 그들이 조회한 재고는 5가 될 것이다. 3명 모두 현재 재고인 5에다가 +1을 하므로 재고는 6이 되는데, 이는 논리적으로 맞지 않게 된다. 재고는 8개가 되어야 하기 때문이다.
하지만, 트랜잭션의 경계가 명확히 존재하면 동시에 여러 사람이 해당 메서드를 호출해도, 한 트랜잭션이 끝나기 전에는 다른 트랜잭션은 재고 데이터에 접근할 수 없게 된다.
트랜잭션의 경계를 명확히 하기 위해서는 @Transactional
을 활용할 수 있다.
💡 트랜잭션 관리
영속성 컨텍스트는 1차 캐시에 등록된 객체에 대해서 변경 사항을 추적하고, 트랜잭션이 커밋될 때 변경 사항을 자동으로 데이터베이스에 반영해 준다. 때문에, 트랜잭션 관리가 영속성 컨텍스트의 특징 중 하나인 것이다.
📌 마무리
ORM과 JPA에 대해 알아보았다. JPA를 사용하면서 변경 감지라는 특징이 있다는 것은 알고 있었지만, Transactional 어노테이션이 없다면, 변경감지가 되지 않는다는 것을 알지 못했었다.
개발하는 데에 활용하던 것들에 대해서 다시 학습하면서 새롭게 알게 되는 것들이 있다. 이를 계기로 어떤 것을 활용하더라도 제대로 이해하고 사용해야겠다는 생각이 들었다.
'TIL' 카테고리의 다른 글
Stream API 이해하기 (0) | 2024.11.24 |
---|---|
가변 객체(Mutable)와 불변 객체(Immutable) (0) | 2024.11.21 |
Set 이해하기 (0) | 2024.11.08 |
LinkedList 이해하고 ArrayList와 비교하기 (3) | 2024.11.05 |
ArrayList의 동작원리 이해하기 (3) | 2024.11.05 |