2012-02-05 2 views
1

동일한 DB에 연결하는 2 개의 프로세스가 있습니다. 첫 번째는 DB에서 읽는 데 사용되고 두 번째는 DB에 쓰는 데 사용됩니다. 첫 번째 프로세스는 리눅스에서 message-queue를 통해 두 번째 프로세스로 실행을위한 쓰기 절차를 보낸다.SQLite 문제 - DB 잠긴 해결 방법

모든 SQL 문은 prepare, step, finalize 루틴에서 사용됩니다. 준비와 단계가 완료 될 때까지 10000 회 반복됩니다 (DB 잠긴 문제를 극복하기 위해이 작업을 수행했습니다).

난 다음 절차를 수행하는 테이블을 추가하는 방법 :

  1. 제 프로세스 = OFF 모드에서 a journal_mode에서의 행의 테이블을 추가하고 쓰레기를 삽입하는 제 2 공정으로 MSG-Q를 통해 요청을 보낸다 .

  2. 그러면 첫 번째 프로세스는 기존 테이블을 검사하여 알고리즘을 계속 진행할 수 있습니다. (이는 반복 사이 usleep 명령 루프를 점검한다.)

문제는 제 2 공정은 공정의 실행에 걸린이다 'PRAGMA의 journal_mode = OFF;' 그것은 DB가 잠겨 있다고 말하기 때문입니다. (여기에서도 이전에 언급했듯이, DB가 10000 시간을 확인하기 위해 usleep을 사용하여 10000 반복의 루프를 사용합니다.)

'기존 테이블 검사'루프의 첫 번째 프로세스에 루프를 추가하면 연결을 닫는 작업이 완료되며 두 번째 프로세스는 정상입니다. 하지만 이제 테이블과 값을 추가 할 때 언젠가 '콜백 요청 쿼리가 중단되었습니다'라는 단계 문이 나옵니다.

여기 무슨 일이 벌어 지는지에 대한 도움이 필요하십니까?

+0

다른 프로세스가 DB에 쓰는 동안 프로세스가 journal_mode를 끄기를 원할 수도 있습니다. journal_mode를 끄기 전에 롤백을 시도하십시오. –

+0

첫 번째 프로세스가 DB에 쓰지 않고 DB 읽기 전용 연결을 가지고 있습니다. 두 번째 프로세스는 journal_mode를 끄고 나중에 해당 DB에 쓰는 프로세스입니다. –

+0

쓰기가 발생하기를 기다리는 동안 판독기 측에 결과 세트/커서가 열려 있습니까? –

답변

2

WAL 모드를 사용하십시오. 그것은 하나의 작가와 아무런 문제없이 독자의 수를 허용합니다. 잠긴 상태를 확인하고 다시 시도 할 필요가 없습니다.

WAL 제한 : DB는 로컬 드라이브에 있어야합니다.

성능 : 대용량 트랜잭션 (1000 초 삽입 등)은 기존 롤백 저널보다 느리지 만 속도가 매우 비슷하거나 그보다 나은 경우도 있습니다. 인식 된 성능 (DB 쓰기가 완료되기를 기다리는 UI)이 크게 향상됩니다.

WAL은 새로운 기술이지만 Firefox, Adroid/iOS 휴대 전화 등에서 이미 사용되었습니다. 2 개의 스레드가 최고 속도로 실행되고 하나의 쓰기와 다른 하나의 읽기에서 테스트를 수행했으며 하나의 문제가 발생하지 않았습니다.

WAL 모드를 사용할 때 앱을 단순화 할 수 있습니다.

+0

WAL이 OFF로 빠르다는 것을 알았습니다. 나는 모든 테이블을 구축해야만하는 init 프로 시저에서 빠른 원인이되어야하며 런타임에는 그 값을 업데이트해야합니다.init 프로 시저의 속도를 높이기위한 제안이 있습니까? init 프로 시저가 런타임 프로 시저로 안정적 일 필요가 없으므로 DB가 손상 될 수 있습니다. –

+0

저널을 사용하지 않고 (Init 중) 실행하는 것은 어떨까요? PRAGMA 동기 = 0 및 locking_mode = EXCLUSIVE를 추가로 사용할 수 있습니다. 그런 다음 표준 설정과 WAL로 DB를 다시 엽니 다. –

+0

동시성에 대해 좀 더 자세히 설명해 드리겠습니다. connection1이 읽기 (준비되지 않은 준비된 문장)를 연 다음 connection2가 쓰기 작업을 수행 한 후 connection1이 읽기를 완료 (완료)해야만 이상한 문제가 발견되었습니다. 쓰다. 조금 복잡해 보이지만 일반적인 교훈은 간단합니다. 읽기와 쓰기가 별도의 연결에서 이루어지는 한 동시성 문제는 없습니다. –