SQLite database is locked 났을 때 원인과 해결: AI 코딩 에이전트로 만든 로컬 앱에서 먼저 볼 것

SQLite database is locked 났을 때 원인과 해결의 핵심은 간단합니다. 동시에 쓰기 작업이 겹쳤거나, 트랜잭션이 닫히지 않았거나, 개발 도구와 앱이 같은 DB 파일을 붙잡고 있는 경우가 대부분입니다.

에러 로그와 DB 접근 코드를 한 화면에 모아두고, Claude Code나 Cursor에 트랜잭션 정리부터 요청해보세요.

특히 Claude Code, Cursor, Codex 같은 AI 코딩 에이전트로 빠르게 로컬 앱을 만들다 보면 FastAPI 백엔드, 백그라운드 워커, 테스트 스크립트가 같은 .sqlite 파일을 동시에 건드리면서 이 에러가 자주 납니다. 먼저 앱을 재시작하기보다 ‘누가 DB를 잡고 있는지’부터 좁히는 게 빠릅니다.

지금 바로 할 일
터미널 2개, DB 뷰어, 백그라운드 워커를 모두 확인한 뒤 아래 체크리스트 순서대로 잠금 원인을 줄여보세요.

에러가 나는 실제 지점은 보통 4곳입니다

SQLite는 가볍고 배포가 쉬워서 개인 자동화, 작은 SaaS 프로토타입, 로컬 AI 도구에 잘 맞습니다. 다만 서버형 DB가 아니라 파일 기반 DB라서 쓰기 동시성에는 한계가 있습니다.

읽기는 여러 프로세스가 해도 괜찮은 편이지만, 쓰기는 한 번에 하나가 안전합니다. 그래서 AI가 만들어준 코드에 긴 트랜잭션, 반복 실행 스크립트, 열려 있는 DB 브라우저가 겹치면 잠금이 생깁니다.

1. 커밋 또는 롤백이 빠진 트랜잭션

가장 흔한 원인입니다. 예외가 발생했는데 commit()이나 rollback()이 실행되지 않으면 연결이 살아 있는 동안 잠금이 남을 수 있습니다. Python이라면 with sqlite3.connect('app.db') as conn: 형태로 컨텍스트 매니저를 쓰면 실수를 줄일 수 있습니다.

2. 개발 도구가 DB 파일을 열어둔 상태

DB Browser for SQLite, TablePlus, DBeaver 같은 도구로 데이터를 보다가 앱을 실행하면 충돌이 날 수 있습니다. 보기만 한다고 생각했는데 편집 모드나 미저장 변경이 남아 있으면 SQLite 입장에서는 잠금 대상입니다.

3. 백그라운드 작업과 API 요청이 동시에 쓰는 구조

예를 들어 FastAPI가 사용자 요청 로그를 저장하고, 동시에 n8n이나 cron 스크립트가 같은 테이블에 결과를 밀어 넣는 상황입니다. 로컬에서는 괜찮아 보이다가 Cursor가 만든 테스트를 병렬로 돌리는 순간 에러가 튀어나오기도 합니다.

4. 너무 짧은 timeout 설정

SQLite 연결 옵션의 timeout이 짧으면 잠금이 아주 잠깐만 있어도 바로 실패합니다. Python 기본값만 믿기보다 sqlite3.connect('app.db', timeout=10)처럼 대기 시간을 늘려 테스트해볼 수 있습니다. 단, timeout은 증상을 완화하는 방법이지 구조 문제를 없애는 해결책은 아닙니다.

빠른 진단표: 증상별로 어디를 볼까

증상 가능성이 큰 원인 바로 해볼 조치 장기 개선
앱 실행 직후 바로 실패 DB 뷰어 또는 이전 프로세스가 파일 점유 DB Browser, TablePlus 종료 후 재실행 개발용 DB와 확인용 복사본 분리
특정 API 호출 때만 발생 커밋 누락, 긴 트랜잭션 예외 처리에 rollback 추가 DB 접근 레이어를 함수 하나로 통일
테스트 병렬 실행 시 발생 여러 테스트가 같은 파일 사용 테스트 워커별 DB 파일 분리 pytest fixture에서 임시 DB 생성
자동화 워커가 돌 때만 발생 API와 cron/n8n 작업의 동시 쓰기 작업 시간을 분리하거나 큐 사용 PostgreSQL 전환 검토

제가 쓰는 점검 순서

AI 에이전트가 만든 로컬 도구를 검수할 때는 코드를 고치기 전에 실행 환경부터 봅니다. 의외로 코드 문제가 아니라 ‘열려 있는 프로그램’이 원인인 경우가 많기 때문입니다.

  1. DB Browser for SQLite, DBeaver, TablePlus를 모두 닫습니다.
  2. 개발 서버, 워커, 테스트 프로세스를 종료합니다. macOS/Linux라면 lsof app.db로 점유 프로세스를 확인합니다.
  3. 트랜잭션 코드에 commit, rollback, close가 있는지 봅니다.
  4. 반복 쓰기 작업이 있다면 한 번의 큰 트랜잭션보다 짧게 나눕니다.
  5. 그래도 반복되면 WAL 모드와 timeout을 함께 테스트합니다.

WAL 모드는 읽기와 쓰기가 섞인 앱에서 도움이 될 수 있습니다. 실행은 PRAGMA journal_mode=WAL;입니다. 다만 네트워크 드라이브나 일부 배포 환경에서는 기대와 다르게 동작할 수 있어 운영 환경에서 확인이 필요합니다.

구체적인 예: AI가 만든 작업 로그 앱에서 난 경우

가상의 예로, Claude Code로 ‘작업 로그를 저장하는 작은 FastAPI 앱’을 만들었다고 해보겠습니다. API는 요청마다 logs 테이블에 insert하고, 별도 Python 스크립트가 1분마다 오래된 로그를 요약해 summary 테이블에 저장합니다.

처음에는 잘 되다가 Cursor에서 테스트를 여러 개 동시에 실행하자 잠금 에러가 납니다. 이때 해결은 세 단계입니다. 테스트용 DB 파일을 test_app_1.db, test_app_2.db처럼 나누고, 요약 스크립트는 앱 실행 중 자동으로 돌지 않게 분리합니다. 마지막으로 DB 쓰기 함수에 timeout=10과 예외 시 rollback을 넣습니다.

이렇게 하면 단순 재시작보다 원인을 명확히 줄일 수 있습니다. 실제 결과는 코드 구조와 실행 환경에 따라 달라질 수 있습니다.

어떤 선택이 맞을까: SQLite 유지 vs PostgreSQL 전환

SQLite를 계속 써도 되는 경우

개인용 대시보드, 로컬 자동화, 내부 프로토타입, 읽기 위주의 작은 앱이라면 SQLite가 여전히 좋습니다. 배포 파일이 적고 백업도 쉽습니다. 단, 쓰기 작업을 한 흐름으로 모으고 DB 뷰어를 동시에 열어두지 않는 습관이 필요합니다.

PostgreSQL을 고려할 경우

여러 사용자가 동시에 글을 쓰거나, n8n·Zapier·Make 같은 자동화 도구가 계속 데이터를 밀어 넣거나, 작업 큐가 여러 개라면 PostgreSQL이 더 적합할 수 있습니다. Supabase, Neon, Railway 같은 관리형 서비스를 쓰면 초기 설정 부담도 줄어듭니다.

흔한 실수 하나: timeout만 늘리고 끝내기

검색해서 timeout=30만 넣고 넘어가면 당장은 조용해질 수 있습니다. 하지만 긴 트랜잭션이나 병렬 쓰기 구조가 그대로라면 데이터 처리량이 늘었을 때 다시 막힙니다.

좋은 순서는 ‘잠금 주체 확인 → 트랜잭션 정리 → 동시 쓰기 줄이기 → timeout/WAL 적용 → 필요하면 DB 교체’입니다. 이 순서로 보면 불필요한 마이그레이션을 줄일 수 있습니다.

자주 묻는 질문

Q. DB 파일을 삭제하면 해결되나요?

개발 중 임시 데이터라면 삭제 후 재생성이 빠를 수 있습니다. 하지만 운영 데이터가 있으면 위험합니다. 먼저 백업을 만들고, 어떤 프로세스가 파일을 잡고 있는지 확인하세요.

Q. WAL 모드를 켜면 잠금 문제가 사라지나요?

읽기와 쓰기가 섞인 상황에서는 도움이 될 수 있지만 모든 동시 쓰기 문제를 해결하지는 않습니다. 쓰기 작업이 여러 곳에서 동시에 몰리면 여전히 충돌할 수 있습니다.

Q. AI 코딩 에이전트에게 뭐라고 시키면 좋나요?

Claude Code나 Cursor에 ‘SQLite 연결을 컨텍스트 매니저로 바꾸고, 예외 시 rollback, timeout 10초, 테스트별 임시 DB를 쓰도록 리팩터링해줘’라고 구체적으로 요청하세요. 단순히 에러를 고쳐달라고 하면 timeout만 추가하고 끝낼 수 있습니다.

Q. 언제 PostgreSQL로 넘어가야 하나요?

동시 쓰기가 핵심 기능이 되었거나, 백그라운드 워커가 여러 개로 늘었거나, 외부 자동화 도구가 계속 같은 DB에 쓰는 구조라면 전환을 검토할 시점입니다.

다음 행동

지금 에러가 난 프로젝트에서 먼저 DB 뷰어와 백그라운드 프로세스를 닫고, lsof 또는 작업 관리자로 점유 상태를 확인하세요. 그다음 AI 에이전트에게 트랜잭션 처리와 테스트 DB 분리를 명확히 지시하면 수정 방향이 훨씬 빨라집니다.

관련 링크

글쓴이 용기

AI 코딩 에이전트로 직접 빌드하는 개발자. Claude Code·Codex 실사용 후기와 빌더 일지를 씁니다.

지식창고