sqlite3 database is locked 问题解决方案
-
sqlite3只支持一写多读.
读与读可以同时进行
读与写不可同时进行
写与写不可同时进行 -
一写多读的案例
场所:男厕所
写: 打扫厕所的女性(一个)
读: 上厕所的男性(多个)
解决方案1
这个问题可以用线程间的同步方案来解决.同步方案的话有多种,但读写锁最适合这个问题.
这个问题和读写锁不谋而合,所以可以用读写锁来解决这个问题.
当然也可以用其他线程间同步方案来解决.
针对读写锁,请参阅线程与读写锁
解决方案2
自己编写函数对当前数据库状态进行判断,并在状态为SQLITE_BUSY的时候一直尝试执行命令
#include <sqlite3.h>
int nCount=0;
int nRet=0;
do
{
nRet = sqlite3_exec( m_db , buf , 0 , 0 , &pErrMsg );
if(nRet != SQLITE_OK){
if (nRet == SQLITE_BUSY)
{
Sleep(1);
continue;
}else{
//TODO
//break;
}
}
} while (1);
解决方案3
通过sqlite3给的函数sqlite3_busy_handler来实现了延时(次数的延时)
sqlite3_busy_handler(db,callback_db,(void *)db);
//如果处于SQLITE_BUSY状态,会调用callback_db函数N次,知道N等于0或者SQLITE_BUSY状态消息. 这里相当一个延时,但并不是延时.与延时不同的是,如果SQLITE_BUSY状态解除,函数会在次数变为0前返回.
sqlite3_exec(db , sqlcmd , NULL, NULL, &zErrMsg );
sqlite3_close(db);
解决方案4
通过sqlite3给的函数sqlite3_busy_timeout来实现了延时(时间的延时)
//sqlite3_busy_timeout实际上是封装了sqlite3_busy_handler,这里面sqlite3_busy_handler调用的是个固定的回调,通过这个回调实现了固定时间的延时.
sqlite3_busy_timeout(db, 30*1000); //最长等待30m ,也相当于延时
sqlite3_exec(db , sqlcmd , NULL, NULL, &zErrMsg );
sqlite3_close(db);