본문 바로가기

전체 글

(27)
익일 쿠폰 발급 자동화를 위해 Spring Scheduler를 적용한 경험 서비스에서 이벤트를 진행하면서 각 사업장의 방문자를 집계하고, 조건을 만족한 사용자에게 쿠폰을 지급해야 하는 요구사항이 생겼다.이 기능은 사용자의 요청으로 실행되는 API가 아니라, 매일 정해진 시간에 자동으로 처리되어야 하는 작업이었다.따라서 Spring Scheduler를 이용해 반복 작업을 자동화했고, 이번 글에서는 회사의 비즈니스 로직은 제외한 채 구현 과정과 설계하면서 고민했던 부분을 정리해보려고 한다 😊 Spring Scheduler는 애플리케이션 내부에서 일정 주기로 작업을 실행할 수 있도록 지원하는 기능이다.이번 기능처럼 사용자의 요청과 관계없이 정해진 시간에 반복 실행되어야 하는 작업을 구현하기에 적합했다. 이번 기능 요구사항 방문 발생 → 방문자 집계 → 발급 대상 조회 → 쿠폰 ..
OTP 2차 인증(2FA) 구현기: Security 생명주기 안으로 인증 흐름 끌어들이기 1. OTP 2차 인증(2FA)이란?아이디와 비밀번호를 입력한 후, 앱이나 문자로 제공되는 일정 시간 유효한 임의의 숫자를 추가로 입력해 계정을 보호하는 강력한 보안 방식입니다.기존에는 ID와 PW를 통한 단순 로그인만 존재했으나, 유저들에게 보다 강력한 보안 옵션을 제공하기 위해 마이페이지에서 2차 인증(ON/OFF)을 설정할 수 있는 OTP 기능을 새롭게 추가하게 되었습니다. 2. 처음 작업할 때 놓쳤던 점 (AS-IS)기능을 처음 구현할 때는 구현 자체에 급급해 Spring Security가 제공하는 강력한 인프라를 제대로 활용하지 못했습니다.대표적으로 아래와 같은 세 가지 설계를 간과하고 있었습니다.Spring Security 인증 흐름 밖에서 처리된 OTP 검증ID/PW 인증은 Security..
JPA 더티 체킹(Dirty Checking) 개념부터 실무 주의사항 (feat. 스냅샷 원리) 💡 JPA Dirty Checking(더티 체킹) 완벽 정리안녕하세요! 오늘은 JPA의 핵심 기능 중 하나인 영속성 컨텍스트(Persistence Context),그중에서도 데이터 수정을 자동화해 주는 더티 체킹(Dirty Checking)에 대해 깊이 있게 다뤄보겠습니다. 1. JPA Dirty Checking(더티 체킹)이란?'Dirty'는 "상태가 변경됨"을, 'Checking'은 "검사함"을 의미합니다.즉, 엔티티의 상태 변화를 감지해서 자동으로 데이터베이스에 반영하는 메커니즘입니다.덕분에 개발자는 별도의 UPDATE 쿼리를 직접 작성하지 않아도 객체의 값만 바꾸는 것으로 데이터를 수정할 수 있습니다.2. 동작 원리: 스냅샷(Snapshot) 비교더티 체킹의 핵심은 영속성 컨텍스트 내부에 저장되..
왜 내 @Transactional은 무시되었을까? (Spring AOP와 Proxy의 함정) 스프링으로 개발하다 보면 분명히 @Transactional을 붙였는데도 롤백이 안 되거나, 데이터가 저장되지 않는 당황스러운 순간이 있습니다.결론부터 말하자면, 이는 스프링이 트랜잭션을 처리하는 '프록시(Proxy) 방식' 때문입니다. 1. Proxy? 대체 왜 그럴까?스프링은 트랜잭션을 처리할 때 빈(Bean)을 생성하며, 이때 실제 객체 대신 이 객체를 감싸는 Proxy(가짜) 객체를 생성합니다.프록시 객체는 일종의 '껍데기'이자 '검문소'입니다.스프링이 @Transactional이 붙은 클래스를 빈으로 만들 때, 실제 클래스 대신 이 가짜 객체를 앞에 세워둡니다.외부 호출 시: Controller → Proxy.method() → [트랜잭션 시작] → RealService.method() → [트..
Spring Boot 3.x + Swagger(OpenAPI 3.1) 완벽 가이드 : 설정부터 보안까지 최소 사양 Java 버전 : 최소 JDK 17 이상 필요 (Spring Boot 3 기본 요구 사양) Jakarta EE : 기존 javax.* 패키지가 아닌 jakarta.* 패키지 기반의 코드로 작성 Spring Security 접근 권한 허용 📌 허용해야 할 주요 경로/v3/api-docs/ : OpenAPI 명세서(JSON/YAML)가 생성되는 경로/swagger-ui/ : Swagger UI 페이지 접속 경로/swagger-ui.html : Swagger UI 메인 엔트리 Swagger 구축 전제 조건 1. Springdoc-openapi v2 사용해야하므로 Gradle 의존성에 버전 추가 및 변경implementation 'org.springdoc:springdoc-openapi-sta..
FTP 배포에서 CI/CD 자동화로 넘어가며 얻은 안정성 FTP 시절의 아찔했던 순간들과거 FTP 배포 시절, 가장 아찔했던 순간은 로컬에서 작업한 소스 파일을 서버로 드래그 앤 드롭할 때였습니다. 무조건적인 덮어쓰기 방식은 개인 작업 시에는 그나마 통제 가능했지만, 협업 상황에서는 동료의 코드를 덮어버려 소스가 꼬이는 대참사가 빈번히 발생하곤 했습니다.더 큰 문제는 로컬과 서버의 환경 차이였습니다. 내 컴퓨터에선 되는데 서버에선 안 되는 현상이 반복되자, 결국 위험을 무릅쓰고 실 서버에 직접 접속해 코드를 수정하는 라이브 코딩 상황까지 벌어졌습니다. 서비스의 안정성보다는 운에 맡기는 배포였던 셈입니다. 😭시간이 흐르며 코드 형상관리의 중요성과 안전한 개발 환경에 대한 요구가 높아졌고, 많은 기업이 현대적인 워크플로우로 눈을 돌리기 시작했습니다. 우리 회사 ..
PHP 레거시 시스템을 Spring Boot로 전환하며 고민했던 기록들 💭 전환 경험을 통한 회고진행했던 시스템 개편 프로젝트는 단순히 언어를 PHP에서 Spring Boot로 바꾸는 것을 넘어, 보안과 안정성을 강화한 현대적 아키텍처로의 재설계를 목표로 했습니다.하지만 과정은 쉽지 않았습니다. 절차 지향적으로 짜여진 기존 코드는 여러 파일과 DB 프로시저에 로직이 파편화되어 있어 비즈니스 흐름을 파악하는 것조차 거대한 도전이었습니다. 여기에 Spring Boot의 Bean 관리와 같은 프레임워크의 구조를 익히고, Thymeleaf를 활용해 프론트엔드까지 통합 구현해야 하는 과제가 주어졌습니다. 이번 포스팅에서는 이러한 '언어의 장벽'과 '구조적 복잡성'이라는 난관을 어떻게 하나씩 풀어내며 시스템을 안착시켰는지, 고민의 흔적들을 기록해보려 합니다. 🚩 자유로운 PHP v..
FK는 왜 걸까? 실무 에러로 배우는 DB 제약 조건 포스팅 전에 앞서,왜 난 이 주제의 포스팅을 생각했을까? 😐 원래 FK를 잘 걸지 않는 편인데 왜냐하면 운영 시 실제 데이터 값을 직접 변경해 줘야 하는 이슈도 생겨 FK 걸린 테이블 내 모든 정보를 수정해 줘야 하는 상황으로 번지고, 하나의 row 를 삭제 시 FK로 물려있어 제약이 많이 걸리기에 운영할 때의 불편함 이슈로 지금껏 대부분 FK를 걸지 않고 테이블 설계를 진행 그러다 이직 후, 협업 중 ERD 설계할 때 FK 조건을 걸게 되는 상황에 놓이게 되어 FK? 너 왜 이렇게 걸리는건데? 싶어 생각 정리 겸 포스팅을 하게 되었습니다. FK(Foreign Key) 란?관계 무결성을 DB 레벨에서 보장해주는 키 FK의 장단점장점1. 데이터 무결성 보장 부모 테이블에 없는 ID가 자식 테이블에 들어오..