본문 바로가기
데이타베이스

[SQLite]Database is locked

by minimax95 2020. 11. 28.

이번 포스팅에서는 SQLite를 이용해서 파일 DB 사용 시 종종 발생하는 Database is locked 오류에 대해 정리해 보겠습니다.

 

응용프로그램에서 1초에 대량의 포인터 정보를 파일 DB에 저장하면서 발생한 에러이며 파일 DB에서 문제가 발생한 파일들을 찾아 이를 해결해 주면 간단하게 해결할 수 있습니다.

 

예외 메시지는 아래와 같이 SQLiteException을 출력합니다.

예외 발생: 'System.Data.SQLite.SQLiteException'(System.Data.SQLite.dll)

code = Busy (5), message = System.Data.SQLite.SQLiteException (0x800007 AF): database is locked

database is locked

   위치: System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)

   위치: System.Data.SQLite.SQLiteDataReader.NextResult()

   위치: System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)

   위치: System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)

   위치: System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior)

   위치: System.Data.SQLite.SQLiteTransaction.Begin(Boolean deferredLock)

   위치: System.Data.SQLite.SQLiteConnection.BeginDbTransaction(IsolationLevel isolationLevel)

   위치: System.Data.SQLite.SQLiteConnection.BeginTransaction()

   위치: HuNOS_DataProcess.DataProcess.TrendProcess.TrendProcessThreadFun() 파일 D:\LWJ\SVN\HuNOS_DataProcess\DataProcess\TrendProcess.cs:줄 303

 

실제 파일 DB의 각 스키마 파일들은 아래의 형태로 저장되며 각 스키마 별로 100 ~1000여개의 Table이 존재합니다.

☞ 스키마 중 Minute 테이블 예시

실제 소스코드 상에서 SQLiteConnection 생성시 생성 옵션을 어떻게 주느냐에 따라 약간의 성능 차이가 발생하지만 'Database is locked'가 발생한 오류 파일을 찾기 위해서는 아래와 같이 SQLiteConnection을 생성해 줍니다.

SQLiteConnection con = new SQLiteConnection(string.Format(Data Source = {0};PRAGMA synchronous=off;PRAGMA auto_vacuum = 1;", FilePath));

위와 같이 SQLiteConnection을 생성해 주면 실제 파일 DB 저장시 원본 파일에 바로 Write를 하지 않고 .journal 확장자를 가진 복사본 파일에 데이터를 저장하고 트렌잭션이 완료되면 원본 파일을 업데이트하는 방식으로 저장하게 되어  'Database is locked' 오류 발생시 원본 파일 DB와 같은 이름의 복사본 .journal 파일을 삭제함으로써 오류를 해결할 수 있습니다.

 

참고로 만약 대량의 데이터 처리시 'Database is locked'의 문제가 없다면 성능면에서 아래와 같은 SQLiteConnection을 생성할 수도 있습니다.

SQLiteConnection con = new SQLiteConnection(string.Format(Data Source = {0};PRAGMA synchronous=off;PRAGMA auto_vacuum = 1;journal mode=off", FilePath));

journal mode 옵션을 off 값으로 설정하여 생성하게 되면 복사본을 만들지 않고 원본 파일에 곧바로 ReadWrite을 하기 때문에 속도면에서 훨씬 우수한 성능을 보실 수 있습니다.

 

이상으로 'Database is locked'오류 해결에 대한 포스팅을 마치겠습니다.

감사합니다.

 

댓글