분류 전체보기53 앱인토스 | 서버, DB없이 미니앱 출시하기 서버도 DB도 없이, 타입을 스키마 삼아 출시한 미니앱 「유류할증료 조회하기」를 정적 타입 데이터만으로 만든 아키텍처 선택과 트레이드오프를 정리해봤습니다.서버를 두지 않은 이유토스 미니앱 유류할증료 조회하기를 만들며 가장 먼저 내린 결정은, 역설적이게도 "무엇을 만들까"가 아니라 "무엇을 만들지 않을까"였습니다. 결론부터 말하면 이 앱에는 백엔드가 없습니다. API 서버도, 데이터베이스도 없고, 8개 국적 항공사의 유류할증료(YQ)를 보여주는 앱인데도 정작 그 값을 받아 오는 네트워크 요청이 한 줄도 없죠. 데이터는 전부 빌드 시점에 자바스크립트 번들 안으로 들어가 있습니다. 이렇게 정한 데엔 몇 가지 이유가 있었습니다. 먼저 초기 앱은 로그인과 결제가 없는 익명 조회 유틸입니다. 기획 단계에서 토스 로.. 2026. 7. 20. 앱인토스 | 미니앱 개발 환경 뜯어보기 백엔드 없는 토스 미니앱을 만들며 파악한 앱인토스 미니앱 개발 환경 뜯어보기 — Granite·ait·TDS·Vite가 어떻게 맞물리는지 부트스트랩부터 배포까지 정리한 개발기입니다. 지난달 유류할증료 조회하기라는 미니앱을 앱인토스(Apps in Toss)에 출시했습니다. 8개 국적 항공사의 유류할증료(YQ)를 항공사별 표와 노선별 비교, 그리고 계산기로 보여 주는 작은 앱이죠. 서버는 한 대도 쓰지 않고, 요금 데이터는 전부 타입이 붙은 정적 상수로 앱 안에 넣었습니다. 로그인도 없습니다. 그만큼 기능은 단순하지만, 정작 처음 며칠을 잡아먹은 건 기능이 아니라 개발 환경 그 자체였습니다. granite dev, ait build, TDS, Vite가 한 프로젝트 안에 뒤섞여 있는데 누가 무엇을 하는지가 .. 2026. 7. 20. 낙관적 락과 비관적 락, 언제 무엇을 선택할까 낙관적 락과 비관적 락, 언제 무엇을 선택할지를 version 컬럼과 SELECT FOR UPDATE로 정리한 글입니다.두 접근의 철학 차이동시에 같은 행을 고치려는 요청이 겹칠 때, 우리가 쓸 수 있는 무기는 크게 두 갈래로 갈립니다. 하나는 "충돌은 어차피 드물 것"이라고 낙관하고 일단 진행한 뒤, 커밋 직전에 "그동안 아무도 안 건드렸지?"를 확인하는 낙관적 락(optimistic lock)입니다. 다른 하나는 "누군가 끼어들지도 모른다"고 비관하고, 읽는 순간부터 그 행에 자물쇠를 채워 놓고 작업하는 비관적 락(pessimistic lock)이죠.이 둘은 성능 튜닝 옵션이 다른 게 아니라 세상을 보는 전제가 다릅니다. 낙관적 락은 충돌이 예외적이라고 가정합니다. 그래서 평소에는 잠금 비용을 전혀 .. 2026. 7. 15. 새벽에 쌓인 데드락(deadlock) 로그를 추적한 밤 새벽에 쌓인 데드락(deadlock) 로그를 추적한 밤의 기록으로, 데드락의 원인과 해결을 정리한 글입니다.데드락은 왜 생기는가데드락을 처음 제대로 마주친 건 결제 정산 배치를 담당하던 시절이었습니다. 개념 자체는 학부 운영체제 시간에 배운 그 순환 대기(circular wait)와 똑같습니다. 두 트랜잭션이 서로가 쥔 자원을 기다리며 영원히 풀리지 않는 매듭에 빠지는 상황이죠. 다만 교과서의 다이어그램과 새벽 3시의 실제 로그는 체감이 많이 다릅니다.가장 단순한 형태를 코드로 그려 보겠습니다. 계좌 A와 계좌 B 사이에서 잔액을 옮기는 두 트랜잭션이 동시에 실행된다고 해 보죠. 하나는 A에서 B로, 다른 하나는 B에서 A로 옮깁니다.-- 트랜잭션 1: A -> B 이체BEGIN;UPDATE accoun.. 2026. 7. 14. 읽기가 쓰기를 안 기다리는 비결, MVCC 읽기가 쓰기를 안 기다리는 비결, MVCC를 스냅샷과 버전 관리 관점에서 정리한 글입니다.왜 읽기는 쓰기를 기다리지 않아도 되는가대시보드 조회 API가 배치 작업이 도는 시간대에만 느려진다는 제보를 받았던 게 몇 년 전 일입니다. 처음 떠올린 그림은 단순했습니다. 배치가 큰 테이블을 통째로 갱신하니, 그 행을 읽으려는 조회 쿼리들이 갱신이 끝날 때까지 줄을 서서 기다린다는 시나리오였죠. 읽기와 쓰기가 같은 데이터를 두고 서로를 막는다, 저는 오랫동안 이게 데이터베이스의 자연스러운 동작이라고 믿고 있었습니다.그런데 PostgreSQL과 MySQL(InnoDB) 같은 요즘 데이터베이스는 그렇게 동작하지 않습니다. 핵심은 MVCC, 즉 다중 버전 동시성 제어(Multi-Version Concurrency Co.. 2026. 7. 13. N+1 문제 - 목록 화면 하나에 쿼리가 300개 나가고 있었습니다 목록 화면 하나에 쿼리가 300개 나가고 있었습니다—N+1 문제와 배치 로딩을 정리한 글입니다.N+1은 어떻게 조용히 생기는가N+1은 이름부터 결과를 그대로 담고 있습니다. 목록을 한 번 조회하는 쿼리 1개, 그리고 그 목록의 각 항목마다 연관 데이터를 다시 읽는 쿼리 N개. 항목이 20개면 21개, 100개면 101개의 쿼리가 나가죠. 무서운 점은 이 패턴이 코드상으로는 전혀 위험해 보이지 않는다는 것입니다.주문 목록을 보여주는 아주 평범한 코드를 예로 들어보겠습니다.# 주문 목록 조회orders = Order.objects.filter(status="paid")for order in orders: # 반복문 안에서 회원 정보 접근 print(order.customer.name)order.c.. 2026. 7. 11. 이전 1 2 3 4 5 ··· 9 다음