전체 글112 MyBatis 암호화 컬럼 추가: Annotation vs TypeHandler 무엇이 정답일까? 시스템 운영 중 개인정보 보호나 보안 강화를 위해 기존 컬럼의 암호화 버전 컬럼을 추가해야 하는 상황이 발생했다. 공통 클래스로 관리하되, 개발 공수를 줄이면서도 성능을 놓치지 않기 위해 두 가지 방식을 두고 고민한 과정을 기록한다.1. 고민의 배경기존 테이블에 phone_num_enc와 같은 암호화 컬럼을 추가하고, Java 애플리케이션에서 DB로 들어갈 때는 암호화, 나올 때는 복호화를 수행해야 한다.환경: Java, Spring Boot, MyBatis핵심 가치: 성능, 유지보수성, 코드의 간결함2. 두 방식의 비교 (Annotation vs TypeHandler)처음에는 Entity/DTO에 어노테이션을 붙여 처리하는 방식이 세련되어 보였으나, 기술적인 깊이를 따져보니 차이가 명확했다.비교 항목A.. 2026. 3. 6. Oracle + Quartz Batch 환경에서 PK Duplicate가 발생하는 이유 — 그리고 왜 이것을 “문제”가 아니라 “받아들여야 할 결과”로 봐야 하는가1. 문제 상황현재 운영 중인 시스템은 Quartz Scheduler를 사용하고 있으며,2개의 애플리케이션 인스턴스가 클러스터링된 환경에서cron trigger 기반으로 배치 작업이 실행되고 있다.quartz.properties 설정을 살펴보면 다음과 같은 클러스터링 관련 설정이 존재했다.org.quartz.jobStore.isClustered = truemisfire 관련 설정 등이로 인해 처음에는 다음과 같이 인식하고 있었다.“Quartz가 클러스터링 환경에서동일한 Job이 동시에 실행되지 않도록 제어해주고 있을 것이다.”그러나 운영 로그를 분석한 결과,동일한 배치 Job이 두 개의 인스턴스에서 동시에 실행된 흔적이 발견되었다.. 2025. 12. 23. @Transactional 사용 시 주의해야 할 7가지 사항 1. @Transactional의 우선순위@Transactional은 적용되는 위치에 따라 다음과 같은 우선순위를 가진다. 구체적인 메소드에 가까울수록 우선순위가 높다.클래스 메소드 -> 클래스 -> 인터페이스 메소드 -> 인터페이스 순으로 적용된다.2. @Transactional의 작동 모드 (Proxy vs. Aspect)@Transactional의 모드에는 Proxy Mode와 Aspect Mode가 있으며, 기본값(Default)은 Proxy Mode다.Proxy Mode (기본 모드)이 모드는 Public 메소드에 적용해야 한다. Protected나 Private 메소드에 선언해도 트랜잭션이 작동하지 않는다.@Transactional은 프록시 객체 외부에서 접근해야만 AOP(Aspect-Orie.. 2025. 12. 1. 배치가 밀릴 때 발생할 수 있는 락(Lock) 이슈와 해결 방안 데이터가 누적되어 배치가 지연되면 단순히 처리가 늦게 끝나는 문제에 그치지 않는다. 트랜잭션을 길게 점유하면서 운영 DB(OLTP)를 마비시키는 락 상황이 발생할 수 있다. 이에 대한 원인과 해결책을 정리했다.1. 문제 원인: 락 발생 메커니즘일반적인 배치는 조회(READ), 가공(PROCESS), 저장(WRITE)의 흐름을 가진다. 여기서 병목과 문제를 유발하는 단계는 주로 저장(WRITE) 단계다.Row Lock (행 잠금) 배치가 데이터를 수정(UPDATE)하거나 삭제(DELETE)하는 순간, 해당 행들은 커밋되기 전까지 잠긴다. 만약 데이터가 밀려 1만 건을 한 번에 업데이트한다면 트랜잭션이 끝날 때까지 1만 건의 데이터가 잠겨 있게 된다. 이때 실제 사용자가 그중 하나의 데이터를 조회하거나 수정.. 2025. 12. 1. RDB 인덱스 작동방식 사전 개념B-Tree(Balanced Tree, 균형 트리)MariaDB가 B-Tree를 사용 시, tree에 노드에 해당하는 것은 페이지(Page)이다.페이지란 16Kbyte 크기의 최소한의 저장 단위이다. → 아무리 작은 데이터를 한 개만 저장하더라도 한 개의 페이지(16Kbyte)를 차지하게 된다는 의미이다.개념적으로 부를 때는 노드라 부르지만, MariaDB에서는 노드가 페이지가 되며 인덱스를 구현할 때 기본적으로 B-tree 구조를 사용한다.B-Tree 구조에서 데이터를 검색하는 방법(이때, 모든 데이터는 정렬되어 있다.)우선 루트 페이지를 검색한다. → 정렬되어 있어서, 해당하는 데이터면 검색 끝, 아니면 범위에 따라서 깊이를 늘려가며 동일한 방식으로 데이터를 검색한다. 인덱스페이지 분할인덱스.. 2025. 10. 7. [Security] 내 security filter chain 구조 이번에 간단한 팀 프로젝트로 인증을 맡게 되었다.정말 많이 배울 수 있었는데, 앞으로도 많은 걸 해야하는 것이구나라고 깨달을 수 있어서 더 의미있는 경험이었다 생각한다. 현재 이 security filter chain에 대한 대략적인 구조도를 기록하고, 나아갈 방향들을 적으려 한다. 1. 구조도 Client에서 요청이 오면 먼저 필터를 거치게 되는데, 내가 설계한 필터 순서는 다음과 같다. 1. logging filter: 거쳐서 들어오는 모든 요청들과 응답들을 찍을 수 있게 하여 디버깅할 때 도움을 줄 수 있도록 함.2. ratelimit filter: bucket4j를 redis에 연결하여서 login 등 인증 api 접근 시 버킷을 차감하여, 정책 상 정해 놓은 상한선을 넘을 시 429 에러를.. 2025. 6. 22. 이전 1 2 3 4 ··· 19 다음