개요
Spring Data JPA와 같은 ORM 프레임워크에서는 엔티티(Entity)를 관리하는 데 있어 영속성 컨텍스트(Persistence Context)가 중요한 역할을 합니다. @Transactional을 사용해왔지만 개념을 좀 더 잡기 위해 글을 작성하도록 했다.
영속성 컨텍스트란?
영속성 컨텍스트는 엔티티의 상태를 관리하는 JPA의 메커니즘입니다. 이는 엔티티를 저장하고, 수정하고, 삭제하는 등의 작업을 수행할 때 JPA가 사용하는 가상의 데이터 저장소라고 할 수 있습니다. 영속성 컨텍스트는 엔티티 매니저(EntityManager)에 의해 관리됩니다.
영속성 컨텍스트의 주요 역할
- 엔티티 저장: 데이터베이스에서 조회된 엔티티나 새로 생성된 엔티티를 영속성 컨텍스트에 저장.
- 변경 추적: 영속성 컨텍스트에 의해 관리되는 엔티티의 상태 변화를 추적.
- 동일성 보장: 동일한 트랜잭션 내에서 동일한 엔티티는 동일한 객체로 보장.
@Transactional 애노테이션
트랜잭션은 데이터베이스에서 일련의 작업들이 모두 성공하거나 모두 실패해야 하는 원자적 단위를 말합니다. 트랜잭션은 다음과 같은 ACID 특성을 가지고 있습니다:
- Atomicity (원자성): 트랜잭션 내의 모든 작업이 성공하거나 모두 실패해야 합니다.
- Consistency (일관성): 트랜잭션이 완료된 후 데이터베이스는 일관성 있는 상태를 유지해야 합니다.
- Isolation (고립성): 동시에 실행되는 트랜잭션은 서로 간섭하지 않아야 합니다.
- Durability (지속성): 트랜잭션이 성공적으로 완료되면 그 결과는 영구적으로 데이터베이스에 반영되어야 합니다.
@Transactional
애노테이션은 메서드나 클래스에 적용되어 트랜잭션의 시작과 종료를 관리합니다. 메서드가 실행될 때 트랜잭션이 시작되고, 메서드 실행이 완료되면 트랜잭션이 커밋되거나 롤백됩니다.
- 트랜잭션 관리: 트랜잭션 시작, 커밋, 롤백을 자동으로 처리.
- 영속성 컨텍스트 관리: 트랜잭션이 커밋될 때 영속성 컨텍스트의 변경 사항을 데이터베이스에 반영.
실행 순서
- 트랜잭션 시작: @Transactional 애노테이션이 있는 메서드가 호출되면 트랜잭션이 시작됩니다.
- 영속성 컨텍스트 활성화: 트랜잭션이 시작되면서 영속성 컨텍스트가 활성화됩니다.
- 엔티티 조작: 엔티티를 조회, 저장, 수정, 삭제 등의 작업을 수행합니다.
- 변경 사항 추적: 영속성 컨텍스트는 엔티티의 상태 변화를 추적합니다.
- 트랜잭션 커밋: 메서드 실행이 완료되면 트랜잭션이 커밋되고, 영속성 컨텍스트의 변경 사항이 데이터베이스에 반영됩니다.
- 트랜잭션 종료: 트랜잭션이 종료되고, 영속성 컨텍스트가 비활성화됩니다.
예제 코드
엔티티 클래스
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getter, Setter, Constructor
public User() {}
public User(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
리포지토리 인터페이스
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
서비스 클래스
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public User createUser(String name) {
User user = new User(name);
return userRepository.save(user);
}
@Transactional
public void updateUser(Long id, String newName) {
User user = userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("User not found"));
user.setName(newName);
// 변경 사항은 트랜잭션이 커밋될 때 자동으로 반영됨
}
}
컨트롤러 클래스
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public User createUser(@RequestParam String name) {
return userService.createUser(name);
}
@PutMapping("/{id}")
public void updateUser(@PathVariable Long id, @RequestParam String name) {
userService.updateUser(id, name);
}
}
마무리
Spring Data JPA에서의 엔티티 관리와 영속성 컨텍스트는 애플리케이션의 데이터 일관성을 유지하는 데 중요한 역할을 합니다.
@Transactional 애노테이션을 통해 메서드 실행 시 트랜잭션을 관리하고, 영속성 컨텍스트의 변경 사항을 자동으로 데이터베이스에 반영할 수 있습니다.
이를 통해 개발자는 데이터베이스 트랜잭션을 더 쉽게 관리하고, 코드의 가독성과 유지보수성을 높일 수 있습니다.
'Spring Boot' 카테고리의 다른 글
[Spring Boot] Redis 설명 및 예제 (0) | 2024.08.22 |
---|---|
[Spring Boot] Spring JPA Entity 연관관계 및 즉시로딩, 지연로딩 (0) | 2024.08.03 |
[Spring Boot] Spring Security @EnableMethodSecurity 설명 및 예제 (0) | 2024.07.10 |
[Spring Boot] @Component와 @Configuration의 특징과 차이점 (0) | 2024.07.09 |
[Spring Boot] BCrypt, SCrypt, Argon2 비밀번호 암호화 기법 (0) | 2024.07.09 |