複数のスレッドから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 件のコメント:
コメントを投稿