1. 비관적 락 select ~ for update 구문을 사용한다. 한 Row의 Lock을 획득하기 하기 위해, 무한정 기다리는 이슈가 발생할 수 있고, 서비스 장애를 야기할 수 있다. (Timeout 설정이 없음) REPEATABLE READ 격리 수준을 사용하고 있다면, 갱신 분실의 문제(Lost Update)가 발생할 수도 있다. RDMBS에서 제공하는 Lock 기능을 사용한다. 언두 영역(InnoDB 스토리지 엔진에 내부에 있는) 레코드에 잠금을 걸 수 없고, 테이블 레코드에 잠금을 건다. 2. JPA에서 지원하는 @Version @Version을 명시하여, 수정이 일어나는 시점에 Version이 일치하지 않으면, 예외를 발생시킨다. REPEATABLE READ 격리 수준에서도 갱신 분실의 문제..
사내에서 진행되는 서비스를 개편하게 되면서, RabbitMQ를 사용하게 되었습니다. RabbitMQ을 사용하고, 운영하면서 Connection과 Channel에 대한 개념이 잡히지 않아서 정리하게 되었습니다. Connection 일반적인 특징 RabbitMQ에서 지원하는 모든 프로토콜은 TCP 기반이다. 효율성을 위해 긴 연결을 가정한다. (프로토콜 작업당 새 연결이 열리지 않음.) 하나의 클라이언트 연결은 단일 TCP 연결을 사용한다. 클라이언트가 연결을 성공하려면, RabbitMQ 대상 노드는 특정 프로토콜에 대한 연결을 허용해야 한다. 연결은 오래 지속되어야 하기 때문에 일반적으로 구독을 등록하고, 폴링 대신에 메시지를 전달하여 소비한다. 연결이 더 이상 필요하지 않은 경우, 리소스 절약을 위해 연..
개발자와 DBA를 위한 Real MySQL을 읽고 정리한 내용입니다. 그중에서 현재 사용하고 있는 InnoDB 스토리지 엔진에 대해 알아보고자 공부하고, 정리하게 되었습니다. 우선 InnoDB 스토리지 엔진의 가장 큰 특징은 다음과 같습니다. 레코드 기반의 잠금 제공 레코드 기반의 잠금 덕분에 높은 동시성 처리 가능 안정적이며, 성능이 뛰어남 InnoDB 스토리지 엔진의 특성 프라이머리 키에 의한 클러스터링 프라이머리 키 값의 순서대로 디스크에 저장된다. 프라이머리 키에 의한 Range Scan은 상당히 빨리 처리될 수 있다. 쿼리의 실행 계획에서 프라이머리 키는 기본적으로 보조 인덱스에 비해 비중이 높게 설정되어 있다. 잠금이 필요 없는 일관된 읽기 MVCC(Multi Version Concurrenc..
전략 패턴이란 같은 기능이지만, 서로 다른 전략을 가진 클래스들을 캡슐화하여 상호 교환할 수 있도록 도와주는 디자인 패턴입니다. 전략 패턴 예시 현재 시스템은 VIP 회원에 대한 2,000원 할인을 해주는 정책을 기본적으로 제공하고 있으며, 상황에 따라 새로운 정책이 추가될 가능성이 높은 상황입니다. 아래의 코드를 보면서 전략 패턴을 설명하도록 하겠습니다. 회원 등급을 가지고 있는 Member 클래스 public class Member { private final Long id; private final String name; private final Grade grade; public enum Grade { BASIC, VIP } public Member(Long id, String name) { th..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/rHDn2/btre5bsTHvI/8S7KNjkmJm8DQNKkt9PO6K/img.png)
사용자는 C 타입 형태만 지원하는 맥북을 구매했습니다. 사용자가 USB 포트를 사용하려면, USB와 C 타입을 호환할 수 있는 어댑터가 필요하게 됩니다. 사용자는 어댑터를 통해 어떠한 USB 포트를 가져와도 문제없이 C 타입의 맥북을 사용할 수 있습니다. 이처럼 어댑터 패턴은 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 동작하도록 해주는 패턴입니다. Client Adaptee를 사용하려는 사용자를 의미한다. Adaptee 라이브러리나 외부 시스템을 의미한다. Adapter Client와 Adaptee 중간에서 호환성이 없는 둘을 연결시켜주는 역할이다. Target Interface를 구현하며, Client는 TargetInterface를 통해 Adapter에 요청을 보낸다. Ad..
MongoDB를 사용하여 간단한 프로젝트를 진행하는 도중, MongoDB 인증을 설정하는 방법에 대해서 정리해봤습니다. (Docker 기반의 내용을 다루고 있습니다.) docker-compose를 통한 Mongo 컨테이너 실행 docker-compose.yml는 아래와 같은 내용들로 정의되어 있습니다. version: '3.3' services: my-mongo: image: mongo container_name: my-mongo ports: - "27017:27017" # Authentication를 설정하기 위해서, command: [--auth]를 주석 처리해야한다. 나머지 내용은 따로 정리하고 링크를 달 것! # command: [--auth] restart: always netwo..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/ciEPVL/btq27gANIOf/MMagm9NbneIh1HPTwtkapK/img.png)
프로젝트를 진행하다가 Entity를 제대로 설계하지 않아서 MappingException: Repeated column in mapping for entity 에러가 발생했고, 이와 관련해서 간단히 정리해봤습니다.문제 상황 (예시) EntityA @Entity @NoArgsConstructor public class EntityA { @Id @GeneratedValue private Long id; @Column(name = "member_id") private Long memberId; public EntityA(Long memberId) { this.memberId = memberId; } } EntityB EntityB에는 Long 타입의 memberId 필드를 선언했고, OneToOne 관계의 E..
![](http://i1.daumcdn.net/thumb/C148x148/?fname=https://blog.kakaocdn.net/dn/Ycj53/btq2Mp5KaZB/3BW4F9PtoqXlX80NmhdVrK/img.png)
Spring Batch Application과 JPA, JDBC를 함께 사용하여 Batch 작업을 처리해야 하는 상황이 있었습니다. 이때 MySQL Connector/J (JDBC Reference) - Configuration Properties for Connector/J 에서 제공하는 기능들을 몰랐기에, 원하는 대로 동작하지 않았던 문제가 있었습니다. 문제 상황 (예시) 데이터를 가공해서 1,000 ~ 150,000개의 데이터를 Pay 테이블에 넣어야 하는 상황이었습니다. MySQL을 사용하는 상황이었고, JPA의 IDENTITY 방식으로 Batch Insert를 활용하기에는 성능적으로 좋지 않은 부분들이 있었습니다. 이를 해결하기 위해서 JdbcTemplate의 batchUpdate를 활용해서 B..