button('hey')
вызывает функцию, а не устанавливает ее как обратный вызов.
По умолчанию sqlite возвращает immediatly с заблокированной, занятой ошибкой, если база данных занята и заблокирована. Можно попросить его ожидать и продолжать пробовать некоторое время перед отказом. Это обычно решает проблему, если у Вас действительно нет 1000-х потоков, получающих доступ к Вашему дб, когда я соглашаюсь, что sqlite был бы несоответствующим.
// set SQLite to wait and retry for up to 100ms if database locked sqlite3_busy_timeout( db, 100 );
Argh - отрава моего существования за прошлую неделю. Sqlite3 блокирует файл дб когда любой процесс записи к базе данных. IE любой ОБНОВЛЯЕТ/ВСТАВЛЯЕТ запрос типа (также избранное количество (*) по некоторым причинам). Однако это обрабатывает несколько чтений очень хорошо.
Так, я наконец был расстроен достаточно для записи моего собственного кода блокировки потока вокруг вызовов базы данных. Путем обеспечения, что приложение может только иметь один поток, пишущий в базу данных в любой точке, я смог масштабироваться к 1000-м потоков.
И да, его медленное как ад. Но также достаточно быстрый и корректный , который является хорошим свойством для имения.
Я полагаю, что это происходит когда временные лимиты транзакции. Действительно необходимо использовать "реальную" базу данных. Что-то как Моросящий дождь или MySQL. Какая-либо причина, почему Вы предпочитаете SQLite по двум предшествующим опциям?
К какой таблице получают доступ, когда с блокировкой встречаются?
у Вас есть продолжительные транзакции?
можно ли выяснить, какие запросы все еще обрабатывались, когда с блокировкой встретились?
Источник: эта ссылка
- Open the database
db = sqlite3.open("filename")
-- Ten attempts are made to proceed, if the database is locked
function my_busy_handler(attempts_made)
if attempts_made < 10 then
return true
else
return false
end
end
-- Set the new busy handler
db:set_busy_handler(my_busy_handler)
-- Use the database
db:exec(...)
Sqlite может позволить другим процессам дождаться завершения текущего.
Я использую эту линию для подключения, когда я знаю, что у меня может быть несколько процессов, пытающихся получить доступ к Sqlite DB:
conn = sqlite3.connect ('filename', изоляция_level = 'exclusive' )
Согласно документации Python Sqlite:
Вы можете контролировать, какой тип НАЧАТЬ заявления pysqlite неявно выполняется (или вообще не выполняется) через Параметр изоляция на уровне вызов connect () или через свойство изоляционного уровня connections.
Вы упомянули, что это сайт Rails. Rails позволяет вам установить время ожидания повторения SQLite в файле конфигурации database.yml:
production:
adapter: sqlite3
database: db/mysite_prod.sqlite3
timeout: 10000
Значение времени ожидания указывается в миллисекундах. Увеличение его до 10 или 15 секунд должно уменьшить число исключений BusyException, которые вы видите в своем журнале.
Хотя это всего лишь временное решение. Если ваш сайт нуждается в истинном параллелизме, вам придется перейти на другой механизм БД.