これは私の最初の投稿です。手がかりが足りず、この特定の問題について何も見つけることができなかったため、質問しています。
私の質問は次のとおりです: Adobe AIRでは、同期usleep()と同等の方法(200ミリ秒の遅延実行)を行う方法はありますか?代わりに、SQLiteのビジータイムアウトをどこかに指定する方法はありますか?
コードが SQL クエリのイベント/コールバックの必要性に対応できないため、同期モードでデータベースを使用する AIR アプリケーションがあります。
データベースは、別のアプリケーションからアクセスされてビジー状態になることがあります。したがって、ステートメントの execute() は SQL エラー 3119 詳細 2206 をスローします。この場合、コマンドは少し遅れて再試行されます。
コンピューターで別のアプリケーションが実行されているため、ビジー状態の待機を回避したいのですが、次の 3 つの理由で行き詰っています。
まず、関数 sqlite3_busy_timeout() を使用して C で可能なように、SQLConnection にビジー タイムアウト値を与える方法を見つけることができませんでした。
次に、Adobe AIR / Actionscript で C の usleep() コマンドに相当するものを見つけることができませんでした。
第三に、この場所ではイベント/タイマー/コールバックなどを使用できません。SQL execute() は、アプリケーション内の無数の場所にある深くネストされたクラスと関数から呼び出されるため、同期的である必要があります。
アプリケーションが SQL の実行中にイベント/コールバックに対処できる場合は、とにかく非同期データベースを使用するため、この問題はイベントを使用して解決することはできません。再試行は、AIR イベント処理機能を使用せずに、最下位レベルで実行する必要があります。
最低レベルのコードは次のようになります。
private static function retried(fn:Function):void {
var loops:int = 0;
for (;;) {
try {
fn();
if (loops)
trace("database available again, "+loops+" loops");
return;
} catch (e:Error) {
if (e is SQLError && e.errorID==3119) {
if (!loops)
trace("database locked, retrying");
loops++;
// Braindead AIR does not provide a synchronous sleep
// so we busy loop here
continue;
}
trace(e.getStackTrace());
trace(e);
throw e;
}
}
}
この関数の使用例は次のとおりです。
protected static function begin(conn:SQLConnection):void {
retried(function():void{
conn.begin(SQLTransactionLockType.EXCLUSIVE);
});
}
このコードの出力は次のようになります。
database locked, retrying
database available again, 5100 loops
読む: アプリケーションは 1 秒間に 500 回以上ループします。アプリはバッテリーでラップトップ上で実行されるため、待機中の CPU 負荷を軽減するために、これをどうにかして 5 ループに減らしたいと考えています。
ありがとう。
-ティノ