【问题标题】:Unable to close sqlite3 database with ruby无法使用 ruby​​ 关闭 sqlite3 数据库
【发布时间】:2019-09-21 09:51:30
【问题描述】:
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 Q 建议在声明中使用finalize,但这似乎只与 C/C++ 接口相关,与 ruby​​ 的 sqlite3 无关。

【问题讨论】:

    标签: ruby database sqlite


    【解决方案1】:

    阅读 ruby​​ gem 的源代码很有帮助。特别是文件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(例如,在我的代码中.execute 之后使用dbins.close)将完成语句并使我能够关闭数据库文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多