sqlite多进程并发读写模式下,返回SQLITE_BUSY错误的处理方法

 SQLite作为一款小型的嵌入式数据库,本身没有提供复杂的锁定机制,无法内部管理多路并发下的数据操作同步问题,更谈不上优化,所以涉及到多路并发的情况,需要外部进行读写锁控制,否则SQLite会返回SQLITE_BUSY错误,以驳回相关请求,这是由于使用当前连接访问数据时,要申请相应级别的锁,而各个级别的锁有些是互斥的,当申请不到锁时就会返回这个错误。这时只要稍等片刻,等其它连接的操作处理完,释放了相斥的锁之后就可以取得锁并进行操作了。

返回SQLITE_BUSY主要有以下几种情况:
1、当有写操作时,其他读操作会被驳回
2、当有写操作时,其他写操作会被驳回
3、当开启事务时,在提交事务之前,其他写操作会被驳回
4、当开启事务时,在提交事务之前,其他事务请求会被驳回
5、当有读操作时,其他写操作会被驳回
6、读操作之间能够并发执行


可采用三种方式处理SQLITE_BUSY

1、用信号量做PV操作

sem_p(semid,0);
sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg);
sem_v(semid,0);


2、自定义一个消息循环处理

    int nCount=0;
    int nRet=0;
    do 
    {
        nRet = sqlite3_exec( m_db , buf , 0 , 0 , &pErrMsg );
        
        if (nRet == SQLITE_BUSY)
        {
            Sleep(1);
            continue;
        }
        break;
    } while (1);


3、采用sqlite3的API函数sqlite3_busy_handler() 或sqlite3_busy_timeout()

sqlite3_busy_handler() 函数当检测到当前连接的数据库处于SQLITE_BUSY状态下,会调用回调函数,在回调函数内可以定义一些行为处理

定义回调函数:

int callback_db(void *ptr,int count)  
{  
    usleep(500000);   //如果获取不到锁,等待0.5秒  
    printf("database is locak now,can not write/read.\n");  //每次执行一次回调函数打印一次该信息  
    return 1;    //回调函数返回值为1,则将不断尝试操作数据库。  
}  
参数int count为回调函数执行次数,在此处对count值无需要,所以没有进行打印等操作。

<pre name="code" class="cpp">sqlite3_busy_handler(db,callback_db,(void *)db);   //一直等待,直到获得锁  
sqlite3_exec(db , sqlcmd , NULL, NULL, &zErrMsg );  
sqlite3_close(db);  

 


sqlite3_busy_timeout()的实现是在内部调用sqlite3_busy_handler(),并调用sqlite3自己的回调函数sqliteDefaultBusyCallback
SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
  if( ms>0 ){
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
    db->busyTimeout = ms;
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

在程序中可以在执行数据库命令前调用此函数,第二个参数设置了SQLITE在返回SQLITE_BUSY前需要等待多长的锁清除时间

sqlite3_busy_timeout(db, 30*1000); //最长等待30m
sqlite3_exec(db , sqlcmd , NULL, NULL, &zErrMsg );  
sqlite3_close(db);  







  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值