다중 스레드 애플리케이션에서 SQLite 사용하기
다중 스레드 애플리케이션에서 SQLite 사용하기 (Using SQLite In Multi-Threaded Applications)
SQLite는 세 가지 서로 다른 스레딩 모드(single-thread, multi-thread, serialized)를 지원해요. 이 문서는 각 모드가 무엇인지, 그리고 컴파일 타임, 시작 타임, 런타임에 스레딩 모드를 선택하는 방법을 설명해요.
출처: 문서
본문
1. 개요
SQLite는 세 가지 다른 스레딩 모드를 지원해요:
-
Single-thread. 이 모드에서는 모든 뮤텍스가 비활성화되고, SQLite는 한 번에 둘 이상의 스레드에서 사용하기에 안전하지 않아요.
-
Multi-thread. 이 모드에서는 어떤 단일 데이터베이스 연결이나 그 데이터베이스 연결에서 파생된 객체(prepared statement 같은)가 동시에 두 개 이상의 스레드에서 사용되지 않는다면, SQLite를 여러 스레드에서 안전하게 사용할 수 있어요.
-
Serialized. 직렬화 모드에서는 어떤 SQLite 데이터베이스 연결이나 그런 데이터베이스 연결에서 파생된 객체에 영향 주거나 사용하는 API 호출을 여러 스레드에서 안전하게 할 수 있어요. 개별 객체에 대한 효과는 모든 API 호출이 단일 스레드에서 같은 순서로 이루어진 것과 동일해요. "serialized"라는 이름은 SQLite가 뮤텍스를 사용해 각 객체에 대한 접근을 직렬화한다는 사실에서 비롯됐어요.
스레딩 모드는 컴파일 타임(소스 코드에서 SQLite 라이브러리가 컴파일될 때)이나 시작 타임(SQLite를 사용하려는 애플리케이션이 초기화할 때)이나 런타임(새 SQLite 데이터베이스 연결이 생성될 때)에 선택될 수 있어요. 일반적으로 런타임이 시작 타임을 재정의하고 시작 타임이 컴파일 타임을 재정의해요. 단, single-thread 모드는 한번 선택되면 재정의할 수 없어요.
기본 모드는 serialized예요.
2. 스레딩 모드의 컴파일 타임 선택
SQLITE_THREADSAFE 컴파일 타임 매개변수를 사용해 스레딩 모드를 선택해요. SQLITE_THREADSAFE 컴파일 타임 매개변수가 없으면 serialized 모드가 사용돼요. -DSQLITE_THREADSAFE=1로 명시적으로 만들 수 있어요. -DSQLITE_THREADSAFE=0으로 하면 스레딩 모드가 single-thread예요. -DSQLITE_THREADSAFE=2로 하면 스레딩 모드가 multi-thread예요.
sqlite3_threadsafe() 인터페이스의 반환 값은 컴파일 타임에 설정된 SQLITE_THREADSAFE 값이에요. sqlite3_config() 인터페이스나 sqlite3_open_v2()의 세 번째 인자로 주어진 플래그로 런타임에 이루어진 스레딩 모드 변경을 반영하지 않아요.
컴파일 타임에 single-thread 모드가 선택되면, 중요한 뮤텍스 로직이 빌드에서 생략되어 시작 타임이나 런타임에 multi-thread나 serialized 모드를 활성화하는 것이 불가능해요.
3. 스레딩 모드의 시작 타임 선택
컴파일 타임 스레딩 모드가 single-thread가 아니라고 가정하면, sqlite3_config() 인터페이스를 사용해 초기화 중에 스레딩 모드를 변경할 수 있어요. SQLITE_CONFIG_SINGLETHREAD 동사는 SQLite를 single-thread 모드로, SQLITE_CONFIG_MULTITHREAD 동사는 multi-thread 모드로, SQLITE_CONFIG_SERIALIZED 동사는 serialized 모드로 설정해요.
4. 스레딩 모드의 런타임 선택
single-thread 모드가 컴파일 타임이나 시작 타임에 선택되지 않았다면, 개별 데이터베이스 연결을 multi-thread나 serialized로 만들 수 있어요. 개별 데이터베이스 연결을 single-thread 모드로 낮추는 것은 불가능해요. 컴파일 타임이나 시작 타임 모드가 single-thread라면 개별 데이터베이스 연결을 높이는 것도 불가능해요.
개별 데이터베이스 연결의 스레딩 모드는 sqlite3_open_v2()의 세 번째 인자로 주어진 플래그로 결정돼요. SQLITE_OPEN_NOMUTEX 플래그는 데이터베이스 연결이 multi-thread 모드가 되게 하고, SQLITE_OPEN_FULLMUTEX 플래그는 연결이 serialized 모드가 되게 해요. 두 플래그 모두 지정되지 않거나 sqlite3_open_v2() 대신 sqlite3_open()이나 sqlite3_open16()이 사용되면, 컴파일 타임과 시작 타임 설정이 결정한 기본 모드가 사용돼요.
더 알아보기 (Learn more)
- Threadsafe SQLite — 관련 문서 참조
- sqlite3_config() — 스레딩 모드 설정 인터페이스
- sqlite3_open_v2() — 데이터베이스 연결 열기
- SQLITE_THREADSAFE — 컴파일 타임 옵션