Замена базы данных SQLite при доступе к ней - PullRequest
5 голосов
/ 04 апреля 2011

Я совершенно новичок в SQLite и намереваюсь использовать его в среде M2M / клиент-сервер, где база данных генерируется на сервере, отправляется клиенту в виде файла и используется на клиенте для поиска данных.

Вопрос в том, могу ли я заменить весь файл базы данных, пока клиент использует его одновременно?

Вопрос может показаться глупым, но клиент - тонкий Linuxклиента и для замены файла базы данных временный файл будет переименован в окончательное имя файла.В Linux программа, в которой по-прежнему открыто , более старая версия файла будет по-прежнему обращаться к более старым данным, поскольку старый файл сохраняется ОС до тех пор, пока все файловые дескрипторы не будут закрыты.Только новые open () получат доступ к новой версии файла.

Короче говоря:

  • клиент случайным образом обращается к базе данных SQLite
  • новая версиябазы данных получена с сервера и записана во временный файл
  • , временный файл переименован в файл базы данных SQLite

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

1 Ответ

1 голос
/ 08 апреля 2011

Нет, вы не можете просто заменить открытый файл БД SQLite3.SQLite будет продолжать использовать тот же файловый дескриптор (или дескриптор на языке Windows), если вы не закроете и не откроете свою базу данных заново.Более конкретно:

  • Удаление и замена открытого файла либо бесполезны (Linux), либо невозможны (Windows).SQLite вообще никогда не увидит содержимое нового файла.

  • Перезапись файла БД SQLite3 - рецепт повреждения данных.Из документации SQLite3 :

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

    Произвольная перезапись содержимого файла БД может вызвать целую кучу проблем:

    • Если вам очень повезет, это приведет только к ошибкам БД и заставит вас снова открытьбаза данных в любом случае.
    • В зависимости от того, как вы используете данные, ваше приложение может просто аварийно завершить работу и записать.
    • Приложение может попытаться применить существующий журнал к новому файлу.Звучит больно?Это!
    • Если вам действительно не повезло, пользователь просто вернет недействительные результаты любых запросов.

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

Если это невозможно, следует обновить файл БД клиента в три раза дискретный шаги:

  • Отправка клиентскому приложению сообщения о закрытии БД.Это позволяет приложению фиксировать любые изменения, удалять любые файлы журнала и очищать его внутреннее состояние.
  • Заменить / перезаписать файл.
  • Отправить сообщение клиентскому приложению для повторного открытия.БД.Однако вам придется заново настроить все подготовленные операторы.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...