2010-03-12 2 views
5

Visual C++에서 SQLite3 DB를 사용하여 데이터를 저장하는 앱을 개발하고 있습니다. 보통 그것은 대부분의 시간 트레이에 앉습니다.SQLite 파일 잠금 및 DropBox

또한 여러 대의 PC에서 공유하기 위해 DropBox 폴더에 내 응용 프로그램을 넣을 수있게하고 싶습니다. DropBox가 최근에 자체적으로 업데이트 될 때까지 제대로 작동했습니다. 이제 "사용중인 파일을 동기화 할 수 없습니다"라고 표시됩니다. SQLite 파일이 내 앱에서 열려 있지만 잠금이 공유됩니다. 준비된 문이 있지만 모두 step을 사용한 직후에 다시 설정됩니다.

열려있는 SQLite 데이터베이스 파일을 동기화 할 수있는 방법이 있습니까? 감사! 여기

는 경우에이 도움이, 난 그냥 테스트 (오류 처리)에 사용하는 간단한 래퍼입니다 :

class Statement 
{ 
private: 
    Statement(sqlite3* db, const std::wstring& sql) : db(db) 
    { 
    sqlite3_prepare16_v2(db, sql.c_str(), sql.length() * sizeof(wchar_t), &stmt, NULL); 
    } 

public: 
    ~Statement() { sqlite3_finalize(stmt); } 

public: 
    void reset() { sqlite3_reset(stmt); } 
    int step() { return sqlite3_step(stmt); } 
    int getInt(int i) const { return sqlite3_column_int(stmt, i); } 

    std::wstring getText(int i) const 
    { 
    const wchar_t* v = (const wchar_t*)sqlite3_column_text16(stmt, i); 
    int sz = sqlite3_column_bytes16(stmt, i)/sizeof(wchar_t); 
    return std::wstring(v, v + sz); 
    } 

private: 
    friend class Database; 

    sqlite3* db; 
    sqlite3_stmt* stmt; 
}; 


class Database 
{ 
public: 
    Database(const std::wstring& filename = L"")) : db(NULL) 
    { 
    sqlite3_open16(filename.c_str(), &db); 
    } 

    ~Database() { sqlite3_close(db); } 

    void exec(const std::wstring& sql) 
    { 
    auto_ptr<Statement> st(prepare(sql)); 
    st->step(); 
    } 

    auto_ptr<Statement> prepare(const std::wstring& sql) const 
    { 
    return auto_ptr<Statement>(new Statement(db, sql)); 
    } 

private: 
    sqlite3* db; 
}; 

UPD :는 sqlite3.c에서 잠금 파일 및 LockFileEx에 대한 모든 호출을 주석 시도 - 같은 결과.

UPD2 : 유휴 상태 일 때 sqlite3_close를 호출하려고했습니다 (개념 증명과 동일) - 여전히 동일한 결과입니다! Filemon은 파일이 아직 닫히지 않았으며 잠금 해제 상태임을 나타냅니다.

UPD3 : 자동 커밋 모드가 켜져 있습니다. BEGIN과 COMMIT의 수가 일치합니다 (Transaction 클래스와 RAII가 처리합니다). SQliteManager는 내 앱이 실행되는 동안 DB에 연결할 수 있으며 수정할 수 있습니다.

+1

결과를 sqlite3_close()에서 확인 하시겠습니까? 아마도 준비된 모든 진술을 마무리하지 않았기 때문에 아마도 효과가 없을 것입니다. –

+0

이것은 그 것이었다! 실행중인 백그라운드 백업으로 인해 작동하지 않았습니다. 바보 같은 실수 .. 고마워! 답으로 써 주면 받아 들일 것입니다. –

답변

4

결과를 sqlite3_close()에서 확인하십시오. 아마도 준비된 모든 진술을 마무리하지 않았기 때문에 아마도 효과가 없을 것입니다.

2

어떤 파일 시스템을 사용하고 있습니까?

autocommit이 켜져 있고 귀하의 진술을 저지르고 있습니까? 나는 커밋하지 않는 문제가 있었음을 기억하고 있으며 자물쇠는 계속 머물러 있습니다.

+0

NTFS. 커밋에 대한 좋은 생각입니다, 감사합니다. –

+0

자동 커밋 모드가 켜져 있습니다. BEGIN과 COMMIT의 수가 일치합니다 (Transaction 클래스와 RAII가 처리합니다). 이것은 이유가 아닌 것 같습니다. SQliteManager는 내 앱이 실행되는 동안 DB에 연결할 수 있으며 수정할 수 있습니다. –

2

Alex Pechnikov는 다중 마스터 SQLite 데이터베이스 복제 프로그램 sqlite3-rdiff을 보유하고 있습니다. 당신이 성취하려고 시도하는 것은 아마도 지나친 것이지만, 파일 복제보다 쉽습니다.

또한 SQLite에는 Online Backup API이 있습니다. 이 페이지에는 예제가 있습니다 : 예 2 : 실행중인 데이터베이스의 온라인 백업.

+0

어떻게 자동으로 사용할 수 있는지 생각할 수 없습니다. sqlite3-rdiff에는 Tcl이 필요하며 백업 API를 사용한다는 것은 변경 될 때마다 전체 DB의 복사본을 만드는 것을 의미합니다. –

+0

모든 변경 후에 DropBox가 DB의 사본 (또는 rdiff)을 작성하지 않습니까? 그렇다면 로컬 복사본의 오버 헤드가 크지 않습니다. 그렇지 않다면, DropBox가 필요로하는대로 forter로만 로컬 복사본을 수행하십시오. –