无法使用ruby关闭sqlite3数据库

时间:2019-05-02 20:29:40

标签: ruby database sqlite

begin
    db = SQLite3::Database.open "dbfile.db"
    dbins = db.prepare("INSERT INTO table(a,b,c) VALUES (?,?,?);")
    dbins.execute(vala,valb,valc)
rescue SQLite3::Exception => e
    puts("Something went wrong: " + e)
ensure
    db.close if db
end

这就是我用来打开SQLite3数据库并将数据写入其中的代码。
我的问题是这段代码总是给我以下错误:

unable to close due to unfinalized statements or unfinished backups

如果我删除了db.close if db部分,那么它可以工作,但是在脚本运行了几个小时之后,我收到了too many open files错误。请不要建议我提高我的inode文件限制,这只是解决更大问题的临时解决方案。

我不希望脚本仅使数据库永远保持打开状态,每当发生事件时,我都希望它打开数据库,写入数据并再次关闭它,以达到预期的工作效果。

请注意,由于评论中的原因,this答案无济于事。

我必须做什么才能“完成”语句,以便可以关闭数据库?我试图在关闭数据库之前只添加一个sleep(5),但这没有任何效果。

我发现this问建议在语句中使用finalize,但这似乎只与C / C ++接口有关,与ruby的sqlite3没有关系。

1 个答案:

答案 0 :(得分:1)

阅读红宝石宝石的源代码很有帮助。具体来说,文件statement.c的以下代码块:

/* call-seq: stmt.close
 *
 * Closes the statement by finalizing the underlying statement
 * handle. The statement must not be used after being closed.
 */
static VALUE sqlite3_rb_close(VALUE self)
{
  sqlite3StmtRubyPtr ctx;

  Data_Get_Struct(self, sqlite3StmtRuby, ctx);

  REQUIRE_OPEN_STMT(ctx);

  sqlite3_finalize(ctx->st);
  ctx->st = NULL;

  return self;
}

因此,在语句上使用.close(例如,代码中dbins.close之后的.execute)将最终确定语句并使我能够关闭数据库文件。