유랑하는 나그네의 갱생 기록

だけど素敵な明日を願っている -HANABI, Mr.children-

반응형

Devlog/SpringBoot 7

재고는 왜 음수가 됐을까? - 비관적 락, 낙관적 락, 그리고 트랜잭션이 지켜주지 못하는 것들

Introtl;dr 동시성 문제는 @Transactional 만으로 해결되지 않습니다. 커머스 주문 시스템에서 재고, 쿠폰, 포인트의 동시 접근을 어떻게 제어했는지, 세 가지 동시성 전략의 선택 기준과 판단 과정을 정리해봅시다. 트랜잭션이면 과연 안전할까?주문 API를 구현하고 통합 테스트를 돌렸을 때, 단일 스레드 환경에서는 예측한 대로 완벽하게 동작했습니다. 재고 10개짜리 상품에 10번 주문하면 재고가 0이 되고, 11번째는 정상적으로 예외가 발생했습니다. 하지만 10개의 스레드가 동시에 주문을 요청하는 상황을 테스트하자 문제가 발생했습니다. 트랜잭션 A: SELECT stock FROM options WHERE id = 1; → stock = 10트랜잭션 B: SELECT stock FROM ..

Devlog/SpringBoot 2026.03.06

도메인 순수성을 포기하고 얻은 것들 (순수 POJO vs Rich Domain Model)

Introtl;dr 순수 POJO와 JPA Entity를 완벽히 분리하려다 도메인 클래스에 @Entity를 허용하도록 전면 롤백했고, 프레임워크 종속성은 타협했지만, 비즈니스 로직을 내부에 응집시킨 'Rich Domain Model'의 본질은 완벽하게 지켜냈다-?! 좋은 아키텍처는 결정을 미루는 것이다. 클린 아키텍처나 DDD를 공부하다 보면 귀에 못이 박히도록 듣는 말입니다. 프레임워크나 DB 기술에 종속되지 않는 '순수 도메인'을 만들어야 한다는 뜻이죠. 2026.02.06 - [Devlog/SpringBoot] - 테스트 코드가 알려주는 객체의 책임과 구조의 미학2026.02.13 - [Devlog/SpringBoot] - HOW적 사고에서 벗어나기 - Why? (의도가 있는 설계법) 이전 포스트에..

Devlog/SpringBoot 2026.02.27

HOW적 사고에서 벗어나기 - Why? (의도가 있는 설계법)

Intro설계 문서는 작업 지시서가 아니다과거 프로젝트를 진행하며 작성했던 설계 문서는 단순 기능 구현 목록에 가까웠습니다. 비즈니스의 복잡성을 어떻게 해결할 것인지에 대한 고민보다는, "이 필드는 VARCHAR(100)으로 할지 1000으로 할지", "API 경로는 /users인지 /members인지"와 같은 구현 상세(HOW)에만 집중했습니다. 심지어 통신 패러다임이 완전히 다른 웹소켓(WebSocket)의 Pub/Sub 라우팅 주소까지 REST API 명세서 표에 포함하기도 했습니다. 프로토콜의 특성이나 아키텍처적 의도(WHY)는 고려하지 않은 채, 기존 문서 양식의 빈칸을 채우는 데 급급했던 결과입니다. 이러한 방식은 유지보수 과정에서 큰 비용을 발생시켰습니다. 개발 중 변경 사항이 생기면 문서..

Devlog/SpringBoot 2026.02.13

테스트 코드가 알려주는 객체의 책임과 구조의 미학

Intro좋은 소프트웨어란 무엇인가?얼마 전까지 저는 테스트 코드에 대한 의문을 품고 있었습니다. "이미 예외 케이스까지 생각해서 기능 구현은 다 해놨는데, 예측이 되는 결과에 대해서 테스트 코드를 대체 왜 작성해야 하는거지?""개발자가 예측하지 못하는 케이스는 악의적인 유저의 행동 패턴이 대부분 아닐까?" 이전에도 테스트 코드를 작성해 본적은 있지만, 사실 개발을 도와주는 도구라기보다는 유지보수의 짐에 가까웠습니다. 부끄럽지만 그 당시 작성했던 코드를 살짝 훑어보겠습니다. (백엔드 개발에 처음으로 발을 들였던 그 당시의 코드라 정말 이상한 코드..) 1. 외부 의존성과의 강한 결합 (Dependency Hell)가장 큰 문제는 테스트가 실제 DB와 프레임워크에 끈적하게 달라붙어 있었다는 점입니다.@S..

Devlog/SpringBoot 2026.02.06

[Spring Boot] Properties Encryption

Properties 암호화의 중요성? 첫 번째 프로젝트 발표를 마쳤을 때, 그동안 했던 프로젝트를 GitLab에서 GitHub로 미러링 하는 과정에서 GitGuardian으로부터 메일이 왔었습니다. 외부로 공개되어서는 안 될 value가 노출이 되었던 겁니다. 첫 번째 프로젝트에서는 application.properties에 담겨있는 value들에 대해 암호화 처리를 하지 않았었죠.. 첫 프로젝트라 다들 어수선하기도 했고 미러링에 문제가 생기자 팀원 중 한 명이 properties 파일을 제거해 버렸습니다..  처음부터 properties에 대해 암호화를 적용시켰더라면 이러한 불상사를 막을 수 있었을 텐데..라는 생각이 들었습니다. 그래서? 두 번째 프로젝트부터는 인프라 세팅을 하면서 스켈레톤 프로젝트의..

Devlog/SpringBoot 2024.07.18

[Spring Boot] WebSocket 뜯어보기

⚠︎ 주의 ⚠︎1. 코드에서 악취가 날 수도 있습니다.2. 작성자도 다시 꺼내보기 어려운, 오래전에 작성한 코드입니다. (3년 전)3. "어? 이거 어디서 본 코드 같은데" 네, 맞습니다.Prologue 안녕하세요. 포트폴리오 만들 겸 경험 정리할 겸 글을 쓰게 되었습니다. 저는 어쩌다 보니 프로젝트 3개를 진행하면서 전부 웹소켓을 담당했습니다. 이전 플젝의 리팩터링은 생각지도 못했고 새로운 프로젝트를 진행할 때 조금씩 변형만 했습니다. 이제 와서 제 코드를 살짝 들춰보니 무슨 괴물을 만들어냈는지 모르겠습니다..그래서? 그래도 그때 나름대로 회의하면서 "이렇게하면 성능 최적화가 되는 건가?"하고 구현만 했었는데 .. 성능 테스트도 못했고 만족스러운 결과도 얻지 못했습니다. 그래서! 이 시리즈는 ... 총..

Devlog/SpringBoot 2024.07.13
반응형
TOP