Возможно ли потерять соединение базы данных SQLite?

Я вижу несколько исключений "java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed." из приложения для Android. Я не закрывал связь во многих местах. Также возможно, что соединение закрывается в каком-то другом потоке.

Чтобы убедиться, возможно ли подключение SQLite автоматически закрываться или операционной системой или неявно?

Ответ 1

Этот рекомендует использовать Singleton DatabaseHelper, а некоторые не демонизировать его.

Это указывает на то, что в базе данных не будет просто просто закрываться в течение всего срока службы вашего приложения.

Первый источник @Alex Lockwood

Подход №1: используйте Singleton для создания экземпляра SQLiteOpenHelper

Объявите свой помощник базы данных как статическую переменную экземпляра и используйте Singleton, чтобы гарантировать свойство singleton. Пример кода ниже следует дать вам хорошее представление о том, как DatabaseHelper правильно.

Статический метод getInstance() гарантирует, что только один DatabaseHelper когда-либо существовали в любой момент времени. Если объект sInstance не имеет были инициализированы, один будет создан. Если он уже создан то он просто будет возвращен. Вы не должны инициализировать своего помощника использование объекта с помощью new DatabaseHelper (контекст)! Вместо этого всегда используйте DatabaseHelper.getInstance(контекст), поскольку он гарантирует, что только один помощник базы данных будет существовать на протяжении всего жизненного цикла приложения.

Второй источник @CommonsWare

Наличие одного экземпляра SQLiteOpenHelper может помочь в делетоках. Поскольку все потоки будут разделять общую SQLiteDatabase, обеспечивается синхронизация операций.

Ответ 2

Да - любая база данных соединение может быть закрыта за вашей спиной. Это может произойти на сервере, если dba решит убить ваше соединение. Это может произойти в клиенте, если что-то не работает. Это может произойти внутри jdbc по разным причинам. Это может произойти случайно в вашем коде.

Здесь есть какая-то двусмысленность. Вы сообщаете, что не может выполнить эту операцию, потому что соединение пул закрыто. Ваш пул соединений вряд ли будет закрыт без вашего ведома. Также, если вы правильно используете пул соединений, он снова откроет соединение базы данных, если оно закроется.

Ответ 3

Я только столкнулся с тем, что это произошло несколькими способами:

  • Вы закрываете соединение с базой данных, а не закрываете курсор.

IE:

SQLiteDatabase db = getReadableDatabase();
//Read Operations
//process cursor
db.close(); //closes entire database connection and cursor is invalid throwing an error
  1. Контекст вызывающей активности больше не действителен

Ответ 4

Это мой личный опыт.

После того, как я применил свой код к известному одноэлементному подходу SQLİteOpenHelper, все стало лучше, так как вспомогательный объект синхронизирует все обращения db на этом объекте. Но все-таки это было не самое лучшее.

Видите, все эти файлы синхронизации не очень атомарны, и они происходят в области, в которой у вас нет большого контроля над ней. Предположим, что прямо перед вашим запросом соединение могло быть закрыто каким-то другим потоком, который имеет блокировку.

Вы можете проверить соединение до ваших запросов, но что, если он закрыт? Вы пропускаете то, что вам нужно делать? Или вы реализуете простую синхронизацию для ваших конкретных узлов доступа к базам данных на уровне, где у вас есть элемент управления? Я бы взял второй путь наверняка.