Board logo

Subject: 关于SQLite并发机制问题的Delphi解决方案 [Print This Page]

Author: ouyongke    Time: 2009-10-28 16:27     Subject: 关于SQLite并发机制问题的Delphi解决方案

  问一下SQLite并发机制的问题,或者说是关于WaitForSingleObject这个API的问题:
  我在网上见到了C++关于处理SQLite并发的代码,其中一个例子使用了上面的API,可是我这个API我没有找到清楚一点的说明,不知道谁可以帮个忙,提供一段说明、例子或者其他解决方案都可以。

  以下是引用我找到的文章:



QUOTE:

  SQLite数据库用来处理锁定情况的两个函数
  
  内容简介:
  SQLite数据库在使用的过程中经常发生的数据库异常便是数据库被锁定了(SQLITE_BUSY或者SQLITE_LOCKED)。SQLite对于并发的处理机制是允许同一个进程的多个线程同时读取一个数据库,但是任何时刻只允许一个线程/进程写入数据库。所以必须要对数据库的读写来进行控制。

  SQLite数据库本身用来处理锁定情况的两个函数:

int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);



int sqlite3_busy_timeout(sqlite3*, int ms);

使用这两个函数可以设定当发生数据库锁定的时候,调用什么函数来处理,以及设定锁定时的等待时间。

  当然通常情况下我们还可以用另外一种方法来解决这类问题,那便是设置互斥量。一般情况下我们可以使用互斥量,临界区等来实现。在这里我使用了互斥量,主要是因为我需要在多个不同的进程中并发的访问同一个数据库。用于锁定和解锁的函数如下:

  void Lock()
  {
    if((hCounter = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"kangxiaofang")) == NULL)
    {
      //如果没有其他进程创建这个互斥量,则重新创建
      hCounter = CreateMutex(NULL,FALSE,"kangxiaofang");
      WaitForSingleObject(hCounter,INFINITE);     //---->这里就光只是等待,可是等待完了呢?什么也没干也可以吗? By Ouyongke
    }
    else
    {
      WaitForSingleObject(hCounter,INFINITE);     //---->这里也是 By Ouyongke

    }
  }
  void UnLock()
  {
    //释放使用权
    ReleaseMutex(hCounter);
    //关闭句柄
    CloseHandle(hCounter);
  }

当然我们也可以把等待时间设定为60秒,以免出现死等的现象。具体使用时可以按如下调用:

  //锁定数据库
  Lock();
  rc = sqlite3_exec(db, "BEGIN;", 0, 0, &zErrMsg);
  rc = sqlite3_exec(db, exec, 0, 0, &zErrMsg);
  rc = sqlite3_exec(db, "COMMIT;", 0, 0, &zErrMsg);
  //数据库解锁
  UnLock();

总结:
  经过测试后,你会发现这种方法所需的消耗要小于循环打开数据库的操作。



[ 本帖最后由 ouyongke 于 2009-10-28 16:29 编辑 ]




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0