这两天在项目中用大强度大频率的方法测试时遇到sqlite报database is locked的问题, int sqlite3_busy_timeout(sqlite3*, int ms);
附:===================================================================
static int sqliteDefaultBusyCallback(
void *ptr, /* Database connection */ int count /* Number of times table has been busy */ )
{
#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
static const u8 delays[] = { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; static const u8 totals[] = { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; # define NDELAY (sizeof(delays)/sizeof(delays[0])) sqlite3 *db = (sqlite3 *)ptr; int timeout = db->busyTimeout; int delay, prior;
assert( count>=0 );
if( count < NDELAY ){ delay = delays[count]; prior = totals[count]; }else{ delay = delays[NDELAY-1]; prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); } if( prior + delay > timeout ){ delay = timeout - prior; if( delay<=0 ) return 0; } sqlite3OsSleep(db->pVfs, delay*1000); return 1; #else
sqlite3 *db = (sqlite3 *)ptr;
int timeout = ((sqlite3 *)ptr)->busyTimeout; if( (count+1)*1000 > timeout ){ return 0;//1000>timeout,so timeout must bigger than 1000 } sqlite3OsSleep(db->pVfs, 1000000);//1000ms
return 1;
#endif
}
int sqlite3_busy_timeout(sqlite3 *db, int ms){
if( ms>0 ){ db->busyTimeout = ms; sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); }else{ sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; }
3、解决方法二
加上一个循环判断。while( 1 ) { if( SQLITE_OK != sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg) ) { if( strstr(m_sqlerr_msg, "database is locked") ) { sleep(1); continue; } break; } } 4、解决方法三 用信号量做PV操作 sem_p(semid,0); sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg); sem_v(semid,0); |