5

我正在用 Visual C++ 开发一个应用程序,它使用 SQLite3 DB 来存储数据。通常它大部分时间都放在托盘中。

我还想将我的应用程序放在 DropBox 文件夹中,以便在多台 PC 上共享它。在 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 中注释掉对 LockFile 和 LockFileEx 的所有调用 - 结果相同。

UPD2:尝试在空闲时调用 sqlite3_close(仅作为概念证明) - 结果仍然相同!Filemon 告诉文件仍然没有关闭,只是解锁。

UPD3:自动提交模式已打开。BEGIN 和 COMMIT 的数量匹配(Transaction 和 RAII 类负责)。SQliteManager 能够在我的应用程序运行时连接到数据库并对其进行修改。

4

3 回答 3

4

从 sqlite3_close() 检查结果。也许它不起作用,因为您还没有完成所有准备好的陈述。

于 2010-03-18T03:02:00.383 回答
2

Alex Pechnikov 有一个多主 SQLite 数据库复制程序sqlite3-rdiff。对于您要完成的工作来说,这可能有点矫枉过正,但它可能比文件复制更容易。

SQLite 还有一个在线备份 API;该页面上有一个示例:示例 2:正在运行的数据库的在线备份。

于 2010-03-14T22:45:12.790 回答
2

您使用的是什么文件系统?

您确定自动提交已打开和/或您正在提交您的陈述吗?我记得有一个不提交的问题,并且锁会一直打开。

于 2010-03-14T08:10:01.157 回答