sqlite3 «база данных заблокирована», повторные попытки не исчезнут - PullRequest
4 голосов
/ 12 января 2010

У меня есть база данных sqlite3, доступ к которой осуществляется несколькими потоками (3-4). Мне известны общие ограничения sqlite3 в отношении параллелизма, как указано http://www.sqlite.org/faq.html#q6, но я убежден, что это не проблема.

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

            try:
                Cursor.execute(q, params)
                Connection.commit()
            except sqlite3.IntegrityError:
                Notify
            except sqlite3.OperationalError:
                print sys.exc_info()
                print("DATABASE LOCKED; sleeping for 3 seconds and trying again")
                time.sleep(3)
                Retry

На некоторых прогонах я даже не ударю по этому блоку, но когда я это сделаю, он никогда не выйдет из него (продолжает повторять, но я продолжаю получать ошибку «база данных заблокирована» из exc_info. Если я понимаю читателя Использование блокировки / Writer правильно, некоторое количество ожидания должно помочь с конфликтом. Это звучит как тупик, но я не использую никаких транзакций в моем коде, и каждый SELECT или INSERT просто один. Некоторые потоки, однако, сохраняйте то же соединение, когда они выполняют свою работу (которая включает в себя сочетание SELECTS и INSERTS и других модификаторов).

Я бы оценил это, если бы вы могли затенить это, а также способы его устранения (помимо использования другого механизма базы данных.)

Ответы [ 3 ]

0 голосов
/ 13 января 2010

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

С другой стороны, чтение может продолжаться без получения блокировки, что, я думаю, может работать нормально с менее строгой блокировкой чтения, необходимой sqlite3.

0 голосов
/ 24 марта 2010

Я также пострадал от этого на веб-сайте, на котором было ~ 200 пользователей в день (что перевело, возможно, 1000 просмотров страниц). Попытки просто не помогли (и я, наконец, увеличил их число до 100, с короткими перерывами между снами). Я не помню, какая это была версия SQLite, но я усвоил урок, что если вы хотите иметь надежные параллельные записи в базу данных SQLite, то вам лучше использовать другую базу данных, такую ​​как MySQL или PostgreSQL.

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

0 голосов
/ 12 января 2010

Sqlite блокирует всю базу данных каждый раз, когда вы пытаетесь записать в базу данных. Есть ли шанс, что одна из ваших тем постоянно пишет? Только один поток поражает блокировку базы данных или все покупают один из них?

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