Adobe Air SQLite同步忙超时/SQLite并发访问/避免忙循环
这是我在这里发表的第一篇文章。我问这个问题是因为我没有线索,也无法找到有关此特定问题的任何信息。
我的问题是:在 Adobe AIR 中,有没有办法执行同步 usleep() 等效操作(延迟执行 200 毫秒),或者有没有办法在某处指定 SQLite 繁忙超时?
我有一个AIR 应用程序以同步模式使用数据库,因为代码无法满足 SQL 查询中事件/回调的需求。
数据库有时会从另一个应用程序访问,从而导致数据库繁忙。因此,语句的execute() 会抛出SQLerror 3119 详细信息2206。在这种情况下,应在短暂延迟后重试该命令。
由于计算机上正在运行另一个应用程序,我想尝试避免忙等待,但是由于以下三件事,我坚持了下来:
首先,我无法找到一种方法来为 SQLConnection 提供繁忙超时值,就像它一样在 C 中可以使用函数 sqlite3_busy_timeout()
其次,我无法在 Adobe AIR / Actionscript 中找到与 C usleep() 命令等效的命令。
第三,我无法在此位置使用事件/计时器/回调等。 SQLexecute() 必须是同步的,因为它是从应用程序中无数位置的深层嵌套类和函数调用的。
如果应用程序可以在执行 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
读取:应用程序每秒循环超过 500 次。我想以某种方式将其减少到 5 个循环,以减少等待时的 CPU 负载,因为该应用程序应在使用电池时在笔记本电脑上运行。
谢谢。
-蒂诺
this is my first post here. I'm asking because I ran out of clues and I was unable to find anything about this specific issue.
My question is: In Adobe AIR, is there a way to do a synchronous usleep() equivalent (delay execution of 200ms), alternatively is there a way to specify the SQLite busy timeout somewhere?
I have an AIR application which uses the database in synchronous mode because the code cannot cope with the need of events/callbacks in SQL queries.
The database sometimes is accessed from another application, such that it is busy. Hence the execute() of a statement throws SQLerror 3119 detail 2206. In this case the command shall be retried after a short delay.
As there is another application running on the computer I want to try to avoid busy waiting, however I'm stuck with it because of three things:
First, I was unable to find a way to give the SQLConnection a busy timeout value, like it is possible in C with the function sqlite3_busy_timeout()
Second, I was unable to find the equivalent of the C usleep() command in Adobe AIR / Actionscript.
Third, I am unable to use events/timers/callbacks etc. at this location. The SQL execute() must be synchronous because it is called from deeply nested classes and functions in zillion of places all around in the application.
If the application could cope with events/callbacks while doing SQL I would use an asynchronous database anyway, so this problem cannot be solved using events. The retry must be done on the lowest level without using the AIR event processing facility.
The lowest level of code looks like:
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;
}
}
}
One sample use of this function is:
protected static function begin(conn:SQLConnection):void {
retried(function():void{
conn.begin(SQLTransactionLockType.EXCLUSIVE);
});
}
Output of this code is something like:
database locked, retrying
database available again, 5100 loops
Read: The application loops over 500 times a second. I would like to reduce this to 5 loops somehow to reduce CPU load while waiting, because the App shall run on Laptops while on battery.
Thanks.
-Tino
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论