Не удалось закрыть базу данных sqlite3 с помощью ruby

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.

Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
0
0
323
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Другие вопросы по теме