久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

sqlite遇到database is locked問題的完美解決

 Ebric 2010-12-14
sqlite遇到database is locked問題的完美解決

這兩天在項(xiàng)目中用大強(qiáng)度大頻率的方法測試時(shí)遇到sqlite報(bào)database is locked的問題,
分析下來原因是sqlite對數(shù)據(jù)庫做修改操作時(shí)會(huì)做(文件)鎖使得其它進(jìn)程同一時(shí)間使用時(shí)會(huì)報(bào)該錯(cuò)誤(也就是SQLITE_BUSY),,但如果僅是多進(jìn)程或多線程查詢sqlite是支持的,。
解決方法有:
1,。使用進(jìn)程或線程間的同步機(jī)制以避免同時(shí)操作,;如用信號(hào)量,互斥鎖等(pthread_mutex_lock,,pthread_mutex_unlock),如果你的項(xiàng)目工程較大要求較高的話建議用此方法自行封裝函數(shù)處理同步
2,。使用sqlite提供的兩個(gè)busy handler函數(shù),但對于一個(gè)連接來說,,只能有一個(gè)busy handle,,兩個(gè)函數(shù)會(huì)相互影響,設(shè)置一個(gè)的同時(shí)會(huì)清除另一個(gè),,應(yīng)根據(jù)需要來選擇,。
int sqlite3_busy_handler(sqlite3 *, int (*)(void *, int), void *)
不注冊此函數(shù)時(shí)默認(rèn)回調(diào)函數(shù)為NULL,清除busy handle,,申請不到鎖直接返回;
函數(shù)可以定義一個(gè)回調(diào)函數(shù),當(dāng)出現(xiàn)數(shù)據(jù)庫忙時(shí)sqlite會(huì)調(diào)用該函數(shù)進(jìn)行延時(shí)并返回非0會(huì)重試本次操作,回調(diào)函數(shù)的第二個(gè)參數(shù)會(huì)被傳遞為此次因BUSY忙事件而調(diào)用該函數(shù)的次數(shù),因此你完全可以自行控制多少次后(也就是延時(shí)多少后)才真正返回BUSY;
回調(diào)函數(shù)返回非0,數(shù)據(jù)庫會(huì)重試當(dāng)前操作,,返回0則當(dāng)前操作返回SQLITE_BUSY;

int sqlite3_busy_timeout(sqlite3*, int ms);
不注冊此函數(shù)時(shí)默認(rèn)超時(shí)等待為0,,當(dāng)ms<=0時(shí),清除busy handle,,申請不到鎖直接返回;
定義一個(gè)毫秒數(shù),,當(dāng)未到達(dá)該毫秒數(shù)時(shí),sqlite會(huì)sleep并重試當(dāng)前操作,
如果超過ms毫秒,,仍然申請不到需要的鎖,,當(dāng)前操作返回SQLITE_BUSY;
很多人用這個(gè)函數(shù)沒有成功,其實(shí)只要你仔細(xì)查看sqlite的源碼就會(huì)發(fā)現(xiàn),,
這個(gè)函數(shù)實(shí)際上注冊了一個(gè)默認(rèn)的sqlite3_busy_handler(sqliteDefaultBusyCallback),,而這個(gè)回調(diào)函數(shù)在你的編譯環(huán)境下可能使得第二個(gè)ms參數(shù)必需要大于1000且是他的整數(shù)倍才有意義,由于此默認(rèn)callback函數(shù)延時(shí)較大,建議自己寫回調(diào)函數(shù)然后用slite3_busy_handler注冊,這樣就可以自己用自己的延時(shí)函數(shù)或方法進(jìn)行處理了.

附:===================================================================
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、解決方法二
加上一個(gè)循環(huán)判斷,。
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,、解決方法三
用信號(hào)量做PV操作
sem_p(semid,0);
sqlite3_exec( myconn, sql, 0, 0, &m_sqlerr_msg),;
sem_v(semid,0);

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多