본문 바로가기

스프링20

동시성 문제 해결 1. 문제리뷰삭제 요청에서 단일결과를 예상했지만, 9개의 결과를 리턴한다고 합니다. 예상대로라면 리뷰좋아요는 member당 하나씩 밖에 갖지 못합니다.1-1. 문제 원인리뷰를 저장할 때 동시성 이슈가 발생해서 그렇습니다.Transaction1과 Transaction2가 거의 동시에 시작되어 각각 BEGIN을 합니다.두 트랜잭션 모두 memberId=1, reviewId=1인 데이터를 찾기 위해 findByMemberIdAndReviewId를 호출합니다.빨간색 박스로 표시된 Race Condition 구간에서:Transaction1이 조회했을 때 "결과 없음"을 받습니다 (아직 좋아요가 없으므로)Transaction2도 조회했을 때 "결과 없음"을 받습니다 (Transaction1이 아직 커밋하지 않았으므.. 2024. 12. 22.
[쿼리문 개선] 댓글/대댓글 조회 dto로 받기 && 반복 루프로 인한 추가 쿼리 호출 문제 해결 기존코드PostCommentGetService@Service@RequiredArgsConstructorpublic class PostCommentGetService { private final PostCommentRepositoryCustom postCommentRepositoryCustom; @Transactional public List getPostComment(long postId) { List postCommentList = postCommentRepositoryCustom.findByPostId(postId); List responseList = new ArrayList(); Map responseHashMap = new HashMap();.. 2024. 12. 18.
DB ↔ ENUM 컨버터, 상하위 ENUM으로 명함 도메인 최적화 1. 기존 설계의 한계관심사는 별도의 테이블에서 관리되고 있었습니다. 이를 명함 데이터와 연결하기 위해 관심사 테이블과 명함-관심사 매핑 테이블이 필요했습니다interest 테이블: 관심사 데이터를 저장.id_card_interest_mapping 테이블: 명함(id_card)과 관심사(interest)를 연결.데이터 예시:interest 테이블:idname1GAME2MOVIE3DRAMAid_card_interest 테이블:id_card_idinterest_id101110121021문제점id_card테이블에 관심사를 담지 않고 id_card_interest 테이블에 별도로 저장함에 따라 한 개의 idCard가 여러 행을 차지하기 때문에 데이터 공간 낭비라고 생각하였습니다명함 조회 시, 관심사 테이블과 매.. 2024. 12. 18.
@Transactional 어노테이션에 대한 작동방식 1. @Transactional이란@Transactional은 Spring에서 제공하는 선언적 트랜잭션 관리 방식입니다. 이 어노테이션 하나로 다음과 같은 복잡한 트랜잭션 처리 코드들을 자동으로 처리할 수 있습니다:데이터베이스 커넥션 획득트랜잭션 시작 (setAutoCommit(false)) (비즈니스 로직 실행)정상 완료시 커밋 또는 예외 발생시 롤백커넥션 반환2. @Transactional 동작 원리@Transactional의 동작은 Spring AOP를 기반으로 합니다.프록시 객체는 다음과 같은 트랜잭션 관련 코드를 자동으로 삽입합니다:1) 메서드 호출 전데이터베이스 연결 (Connection 객체 생성).트랜잭션 시작 (setAutoCommit(false)).트랜잭션 동기화 (현재 트랜잭션 정보.. 2024. 12. 16.
서블릿 컨테이너와 스프링 컨테이너의 완벽한 이해 1. 웹 애플리케이션의 기본 구조 이해하기1.1 Web Server와 WAS의 구분Web ServerApache, Nginx와 같은 서버HTML, CSS, JavaScript 등 정적 파일 제공간단한 요청-응답 처리빠른 처리 속도가 장점WASWeb Server + web ContainerTomcat, JBoss와 같은 서버비즈니스 로직 처리데이터베이스 연동동적 컨텐츠 제공1.2 Web Server와 Web Container가 같이 있을 경우WAS는 웹 서버의 기능을 포함하기 때문에 웹 서버의 기능을 제공할 수 있다.WAS와 DB만으로도 시스템 구성이 가능하지만, WAS가 너무 많은 기능을 담당해 서버 과부하의 우려가 생긴다.정적 컨텐츠의 요청까지 WAS가 처리한다면 정적 데이터 처리로 인해 서버에 부하가.. 2024. 12. 13.
OSIV OSIV(Open Session In View)OSIV(open session in view) 는 영속성 컨텍스트를 뷰까지 열어둔다는 의미입니다. 영속성 컨텍스트가 살아있으면 엔티티는 영속 상태로 유지될 수 있어, 뷰에서도 지연 로딩을 사용할 수 있어요. OSIV의 핵심은 뷰에서도 지연 로딩이 가능하도록 하는 것입니다. 가장 단순한 구현은 클라이언트 요청이 들어올때 필터나 인터셉터에서 트랜잭션을 시작하는 방법인데요. 이를 트랜잭션 방식 OSIV라고 합니다. 하지만, 트랜잭션 방식 OSIV는 표현 계층에서도 엔티티를 수정할 수 있기 때문에 유지보수하기 어려운 코드를 만들 수 있습니다.트랜잭션 방식의 OSIV의 문제는 어떻게 풀어볼 수 있을까요? 🤔최신 방식의 OSIV는 트랜잭션 방식의 문제를 해결합니다... 2024. 12. 10.
orElse함수는 잘못 쓰기 쉽다(with orElseGet함수) # 논리 오류를 알게된 경위collectionLike를 데이터베이스에서 찾고 없으면 collectionLike를 새로 만들어 저장하는 코드를 짰다. 코드 검사에서 orElse에 있는 collectionLikeRepository.save()가 항상 호출된다고 위험을 알렸다. @Transactional public void saveCollectionLike(Long memberId, Long collectionId) { Member member = memberRepository.findByIdOrElseThrow(memberId); Collection collection = collectionRepository.findByIdOrElseThrow(collectionId);.. 2024. 10. 9.
Redis 클라이언트 lettuce에 대해서 Redis 클라이언트 3가지Jedis쓰레드 세이프하지 않아 잘 쓰이지 않는다.Lettuce비동기 및 동기식 API를 제공하는 Redis 클라이언트로, Netty 기반으로 구현되어 높은 성능을 자랑합니다.Redis Cluster와 Sentinel을 기본적으로 지원하며, 스레드 세이프한 구조로 멀티스레드 환경에서도 안정적입니다.비동기/리액티브 프로그래밍을 위한 API를 제공하므로, 높은 처리량을 필요로 하는 애플리케이션에 적합합니다.Redisson고급 기능을 제공하는 Redis 클라이언트로, Redis를 분산 데이터 구조로 활용할 수 있게 도와줍니다.분산 락, 분산 맵, 분산 큐와 같은 기능을 기본적으로 제공하며, 이러한 구조를 사용해 분산 애플리케이션을 개발하는 데 유용합니다.즉, 분산환경에서 자원 동기화.. 2024. 9. 12.
몰랐던 어노테이션 정리 1. 테스트 관련 어노테이션# @ParameterizedTest @ParameterizedTest@ValueSource( strings = { "glutenFreeTag", "highProteinTag", "sugarFreeTag", "veganTag", "ketogenicTag" } ) //또는 @ParameterizedTest@EnumSource(value = Category.class)@DisplayName("순서가 없고 카테고리 필터링 조건이 있어도 정상적으로 조회한다.")void getBoardListSuccessWithCategoryCondition(Category catego.. 2024. 8. 7.