SQLite неисключительная блокировка RESERVED?

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

При просмотре документации кажется, что после того, как в транзакции выдается команда обновления, процесс получает ЗАБРОСОВАННУЮ блокировку, что (если я правильно помню) означает, что любой другой процесс, который пытается добавить запрос на обновление к своей собственной транзакции или зафиксировать транзакцию не может сделать это и поэтому блокируется до тех пор, пока транзакция не зафиксирует процесс с блокировкой.

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

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

Обновить: То, что я имею в виду, когда говорю «выполнение всех моих обновлений сразу», по сути, заключается в использовании транзакций в SQLite только для получения ИСКЛЮЧИТЕЛЬНОЙ блокировки и записи на диск только один раз для каждого процесса, а не один раз для каждого запроса. Это приводит к 100-кратному ускорению при использовании SQLite.

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
1 327
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

SQLite поддерживает ПРИКРЕПЛЯТЬ для присоединения одной базы данных к другой базе данных. Возможно, вы сможете накапливать данные в отдельной базе данных, а когда будете готовы объединить накопленные строки, присоединить отдельную базу данных, скопировать строки в одном операторе и отсоединить.

Обновлено: аналогичное предложение для OP было сделано на ветка списка рассылки у пользователей sqlite с некоторым последующим обсуждением.

Это может сработать, но похоже на уродливую уловку. Какая у него производительность?

Kyle Cronin 15.11.2008 05:02

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

Doug Currie 15.11.2008 07:30

Лучше, чем присоединять базу данных, - это просто создать временную таблицу. (СОЗДАТЬ ВРЕМЕННОЕ ...)

И взгляните на новый режим журнала WAL, который делает именно то, что вы пытаетесь сделать вручную, и позволяет одновременную запись и чтение (хотя и не одновременную запись).

#pragma journal_mode = WAL

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