2012年11月10日土曜日

SQLiteでSQLITE_BUSYが返ってくる

Linuxでsqliteライブラリを使っています。

複数のスレッドからSQLiteファイルを操作していると、
sqlite3_step()でSQLITE_BUSY(5)が返ることがある。
 
どうやらSQLiteでは複数スレッドからのDBへの同時アクセスはNGのようで、
即関数リターンしてしまうようです。
うまいこと排他して実行してくれないもんかな?と思ったら、
それはそれで可能なようです。
 
void sqlite_busy_timeout(sqlite*, int ms);
 
データベースopen後にこれを実行することで、step時のタイムアウト値を設定できます。
これをやってやると、複数スレッドから同時アクセスしても、stepでエラーになることは
ありませんでした。

しかし、ここでちょっとした問題が。。。


数10msecの動作を複数スレッドから実施すると、時たまstepに秒オーダーの時間が掛かる
場合があるのです。
どうやらこのタイムアウト、関数内でDB状態をポーリングしていると思われます。

それでもいい、というケースなら問題ないんですが、私の感覚では、余計に掛かる時間が大きすぎます。

で結局、自力でポーリングして実現しました。

だいぶ省略しますが、コードはこんな感じです。

while(++retryCnt < 1000) {
    ret  = sqlite_step()
    if (ret == SQLITE_OK)  break;
    usleep(5000)
}

0 件のコメント:

コメントを投稿