본문 바로가기

JPA7

[Spring & DB] 기존 Named Lock 방식 개선하기 들어가며이전에 Named-Lock 을 통해 동시성을 제어하는 방식과 분산락을 이용하여 제어하는 방식을 비교하며, Named-Lock은 경쟁 상태에 들어가는 요청이 늘어나는 경우에, ConnectionPool 이 고갈되는 현상이 생길 가능성이 존재한다며 단점으로 언급하였었습니다.그 이유로는 이전 글에서 언급하였던 것처럼 락을 획득하고 제어하는 트랜잭션 내에서 또 다른 트랜잭션이 필요하였기 때문입니다. 이러한 생각과 함께 또 다른 생각은 그렇다면 락을 획득하고 제어하는 부분에서는 트랜잭션을 걸지 않고 처리하면 되는 것이 아닐까? 라는 생각이 들었습니다. 하지만 Named Lock 을 해제하기 위해선 획득한 세션과 동일한 세션이 필요하며, 이를 유지하는 방법으로 트랜잭션을 묶어 동일한 커넥션을 가져오도록 강제.. 2025. 7. 6.
[DB & JPA] 무한 스크롤 계층형 댓글 구현하기 들어가며일반적으로 많은 어플리케이션에서 페이지네이션보다는 스크롤 형식의 댓글을 구현하며, 이와 함께 대댓글 기능을 포함하고 있습니다.저 역시 좋은 기회로 작은 사전 과제에서 이러한 기능을 고민하고 구현하는 경험을 할 수 있게 되어서 해당 과정을 공유하고자 글을 작성하게 되었습니다. 요구사항댓글은 하나의 요청(스크롤)에 5개의 댓글을 불러와야합니다. 또한, 대댓글 기능을 지원해야합니다.기존 요구사항은 위와 같이 어떻게 보면 단순하게 무한 스크롤을 통해 댓글을 5개씩만 불러오면 되는 것이 아닌가? 라고 생각할 수 있을 것입니다. 하지만 아래와 같은 부분을 함께 고민하면 좋을 것 같습니다. 1. 앞서 있던 댓글에 대댓글을 작성하면, 해당 대댓글은 어느 시점에 보여야 하는가?2. 만약, 해당 대댓글이 앞선 댓글.. 2025. 5. 24.
[JPA] 영속성 컨텍스트 EntityManager 란?JPA (Java Persistence API)에서 엔티티(Entity)를 관리하는 객체입니다.즉, 데이터베이스와 애플리케이션 사이에서 엔티티의 생명주기를 관리하는 역할을 수행합니다.영속성 컨텍스트란?영속성 컨텍스트란 엔티티를 영구 저장하는 환경입니다. 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 합니다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리합니다.영속성 컨텍스트의 구성 요소1차 캐시 : 식별자 기준 엔티티 저장, 중복 쿼리 방지.쓰기 지연 SQL 저장소 : 트랜잭션 커밋 시 DB 반영용 INSERT/UPDATE 모음변경 감지 : Flush 시점에 변경된 필드 자동 감.. 2025. 4. 11.
[DB & 팀프로젝트] 삽입 작업에서는 어떻게 동시성 제어를 할까? 들어가며이전 글(https://kongdevlog.tistory.com/19)에서는 행 단위 잠금만으로 모든 동시성 문제를 해결할 수 있을 것 같다고 생각을 하였습니다. 하지만 이번 기능을 구현하며, 잘못된 생각이었다는 것을 깨닫게 되었습니다. 문제 상황사용자 A가 다른 사용자 B에게 매칭을 요청하는 기능을 맡아 구현하게 되었습니다. 따라서 저는 아래와 같은 플로우로 코드를 구현하게 되었습니다. 1. A.id 와 B.id 둘 사이의 진행중인 매칭이 존재하는지 확인. 2 - 1. 매칭이 존재한다면 예외를 반환 2 - 2. 매칭이 존재하지 않다면, 매칭 생성. 이 과정을 단순히 하나의 트랜잭션으로 구현하였습니다.@Transactionalpublic void request(Long requesterId, Lo.. 2025. 2. 18.
[팀 프로젝트] 유니크 제약 조건과 동시성 문제 들어가며이전에 작성한 글(https://kongdevlog.tistory.com/16)에서 유니크 키 제약 조건에 대한 이해가 부족하여 오버 엔지니어링(+ 잘못된 작업)을 하게되었습니다.해당 과정에 대한 원인을 분석하고 개념을 정리하기 위해 글을 작성합니다.이전 구현@Transactional public MemberLoginServiceDto login(String phoneNumber) { Member member = createOrFindMemberByPhoneNumber(phoneNumber); if (member.isBanned()) { throw new BannedMemberException(); } ... .. 2025. 2. 1.
[팀 프로젝트] 트랜잭션의 커밋 시점과 동시성 관리 상황@Transactional public MemberLoginServiceDto login(String phoneNumber) { Member member = createOrFindMemberByPhoneNumber(phoneNumber); if (member.isBanned()) { throw new BannedMemberException(); } ... return new MemberLoginServiceDto(accessToken, refreshToken, member.isProfileSettingNeeded()); } private Member createOrFindMemberByPhoneNumbe.. 2025. 1. 28.