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, это будет лишь временным решением более серьезной проблемы.
Я не хочу, чтобы сценарий просто держал базу данных открытой навсегда, всякий раз, когда происходит событие, я хочу, чтобы он открывал базу данных, записывал данные и снова закрывал ее, как и ожидалось.
Обратите внимание, что ответ это не помогает по причине в комментарии, что верно.
Что мне нужно сделать, чтобы «закончить» оператор, чтобы я мог закрыть базу данных? Я пытался просто добавить sleep(5) перед закрытием базы данных, но это не дало никакого эффекта.
Я обнаружил, что это Q предлагает использовать завершить в операторе, но, похоже, это относится только к интерфейсу C/C++, а не к sqlite3 в ruby.

Помогло чтение исходного кода ruby gem. В частности, следующий кодовый блок файла заявление.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 в моем коде) завершит оператор и позволит мне закрыть файл базы данных.