일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 개발자학원
- 트라몰정 325mg
- 인스턴스상태확인
- 백로뜻
- 자바
- 국비개발학원
- java
- 백로특징
- oracle
- MSG워너비나얼
- 요즘말
- 스프링 배치
- 미국 태풍경보센터
- 국비학원리뷰
- 대전 국비
- 슈가먄
- 백로계절
- 오라클
- 스프링 스키마
- 오라클xe
- JAVA1
- 개발자
- 트라몰정
- 국비학원
- 요린이뜻
- OracleSQL
- 엠비엔 편성표
- 테이블 저장 예제
- 테이블객체
- 부린이뜻
- Today
- Total
정보의 보물창고
JPA의 @Lock(LockModeType.PESSIMISTIC_WRITE)와 Oracle의 FOR UPDATE 비교 본문
JPA의 @Lock(LockModeType.PESSIMISTIC_WRITE)와 Oracle의 FOR UPDATE 비교
☆★※☆★※ 2025. 2. 19. 07:56이번에 동시성 제어를 학습하다
JPA에 @Lock(LockModeType.PESSIMISTIC_WRITE)을 알게 되었다.
내가 최근 프로젝트에서 사용한 Oracle의 For Update와 어떤 차이점이 있는지 학습해보았다.
데이터베이스에서 동시성 문제를 처리하기 위한 방법 중 하나는 **비관적 잠금(Pessimistic Locking)**을 사용하는 것이다. 동시성 문제란 여러 트랜잭션이 동일한 데이터를 동시에 수정하려 할 때 발생하는 문제를 의미한다. 이 문제를 해결하기 위해 자주 사용되는 방법은 **FOR UPDATE**와 **@Lock(LockModeType.PESSIMISTIC_WRITE)**이다. 두 방법은 기능적으로 유사하지만, 사용 방식에는 차이가 있다.
1. FOR UPDATE란?
FOR UPDATE는 SQL에서 사용되는 구문으로, 특정 레코드를 조회하면서 해당 레코드에 쓰기 잠금을 걸어 다른 트랜잭션이 이를 수정하지 못하게 한다. 예를 들어, 상품 재고를 수정하는 상황에서 두 명의 고객이 동시에 동일한 상품을 구매하려고 할 때, 재고가 중복으로 수정되는 문제를 막기 위해 FOR UPDATE를 사용한다.
-- 상품 재고를 확인하고 잠그기
SELECT stock FROM products WHERE product\_id \= 101 FOR UPDATE;
위 쿼리는 product_id가 101인 상품의 재고를 조회하면서, 해당 레코드에 잠금을 걸어 다른 트랜잭션이 이 데이터를 수정할 수 없도록 한다. 잠금이 풀릴 때까지 다른 트랜잭션은 대기해야 한다.
2. JPA의 @Lock(LockModeType.PESSIMISTIC_WRITE)란?
JPA에서는 @Lock 애너테이션을 사용하여 비관적 잠금을 쉽게 구현할 수 있다. @Lock(LockModeType.PESSIMISTIC_WRITE)는 JPA가 실행하는 쿼리에 대해 쓰기 잠금을 걸어 다른 트랜잭션이 해당 엔티티를 수정하지 못하게 한다. 내부적으로는 FOR UPDATE와 유사한 SQL 쿼리를 실행한다.
@Lock(LockModeType.PESSIMISTIC\_WRITE)
@Query("SELECT p FROM Product p WHERE p.productId = :productId")
Product findProductWithLock(@Param("productId") Long productId);
위 코드에서 @Lock(LockModeType.PESSIMISTIC_WRITE)는 JPA가 해당 상품을 조회하면서 자동으로 잠금을 걸도록 한다. 이 방식은 JPA가 내부적으로 FOR UPDATE와 같은 쿼리를 실행하기 때문에, 결과적으로 동일한 잠금 기능을 제공한다.
3. 두 방법의 차이점
FOR UPDATE와 @Lock(LockModeType.PESSIMISTIC_WRITE)는 기능적으로 동일한 역할을 한다. 두 방법 모두 특정 데이터를 잠그고, 다른 트랜잭션이 그 데이터를 수정하지 못하게 한다. 하지만 사용 방식에는 차이가 있다.
- **FOR UPDATE**는 SQL에서 직접 사용하는 구문이다. 이 방식은 특정 데이터베이스에서만 동작할 수 있으며, 예를 들어 Oracle에서는 잘 동작하지만, 다른 DB에서는 다르게 처리될 수 있다. 즉, DB에 종속적인 방식이다.
- **@Lock(LockModeType.PESSIMISTIC_WRITE)**는 JPA에서 제공하는 추상화된 방법이다. JPA는 내부적으로 DB에 맞게 FOR UPDATE와 유사한 쿼리를 실행하므로, DB에 종속되지 않고 일관되게 동작할 수 있다.
4. 예시: DB 변경 시 어떤 방식이 더 유리할까?
예를 들어, 처음에는 Oracle DB를 사용해서 프로젝트를 개발했는데, 이후 MySQL로 DB를 변경해야 하는 상황을 생각해 보자. 이 경우 FOR UPDATE를 사용하는 방식과 @Lock(LockModeType.PESSIMISTIC_WRITE)를 사용하는 방식의 차이를 살펴보자.
- FOR UPDATE 사용 시: DB가 변경되면 기존에 작성한 FOR UPDATE 쿼리가 MySQL에서 예상대로 동작하지 않을 수 있다. 각 DB마다 FOR UPDATE의 동작 방식이 다를 수 있기 때문에, DB가 변경될 때마다 쿼리를 수정해야 할 수 있다.
- @Lock(LockModeType.PESSIMISTIC_WRITE) 사용 시: JPA에서 제공하는 추상화된 방법은 DB가 변경되더라도 JPA가 내부적으로 처리해주기 때문에, 쿼리를 수정할 필요가 없다. 즉, DB 변경에 유연하고, 일관된 방식으로 동시성 문제를 해결할 수 있다.
5. 결론
FOR UPDATE와 @Lock(LockModeType.PESSIMISTIC_WRITE)는 기본적으로 동일한 기능을 제공한다. 두 방법 모두 데이터를 잠그고, 다른 트랜잭션이 그 데이터를 수정하지 못하게 하며, 쓰기 잠금을 구현하는 역할을 한다. 하지만 DB에 종속적인 SQL을 사용하는 FOR UPDATE와, 추상화된 방법인 @Lock(LockModeType.PESSIMISTIC_WRITE)는 사용 환경에 따라 선택해야 한다.
- 직접 SQL을 작성하는 경우에는 FOR UPDATE를 사용하는 것이 적합하다. 특정 DB에 종속적인 쿼리 작성을 원할 때 유용하다.
- JPA를 사용하는 경우에는 @Lock(LockModeType.PESSIMISTIC_WRITE)가 더 효율적이다. JPA는 DB에 맞춰 내부적으로 쿼리를 처리하므로, DB 종류에 관계없이 일관된 방식으로 동시성 문제를 해결할 수 있다.
따라서, JPA를 사용할 때는 @Lock을 사용하고, DB에 맞춰 직접 SQL을 다루는 경우에는 FOR UPDATE를 사용하는 것이 좋다.
'개발 Memo > Spring' 카테고리의 다른 글
[스프링 배치] 스프링 배치 테이블 구조 (0) | 2023.12.31 |
---|