2013-08-13 2 views
7

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

conn = connect('test.db') 

with conn: 
    for v in xrange(10): 
     tup = (str(v), v) 
     conn.execute("insert into sometable values (?,?)", tup) 

выполнить сразу же, они будут делать исключение? Подождите вежливо, чтобы другие процессы писали? Есть ли лучший способ сделать это?

+1

Не уверен, что это дуплекс: я спрашиваю о поведении конкретного модуля python, а не SQLite вообще. – Shep

ответ

16

Библиотека sqlite блокирует базу данных за процесс при записи в базу данных, и каждый процесс будет ждать выхода блокировки, чтобы получить свою очередь.

Базу данных не нужно писать до совершить время. Вы используете соединение в качестве менеджера контекста (хорошо!), Поэтому фиксация происходит после завершения цикла и выполняются все операторы insert.

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

+1

, так что блокировка включена в 'connect' или когда происходит фиксация? – Shep

+1

Блокировка захватывается при записи. –

+1

@MartijnPieters ... и блокировка освобождается при возврате из вызова функции фиксации. Или я ошибаюсь? –

4

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

http://docs.python.org/2/library/sqlite3.html#sqlite3.connect

Не рекомендуется иметь свой файл базы данных в сетевом ресурсе.

Обновление:

Вы также можете проверить уровень изоляции: http://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.isolation_level

0

Хорошая новость заключается в том, что библиотека SQLLite неявно использует транзакции, которая блокирует базу данных всякий раз, когда выполнение DML. Это означает, что другие одновременные обращения к базе данных будут ждать завершения выполнения DML-запроса, совершив/отменив транзакцию. Обратите внимание, однако, что несколько процессов могут выполнять SELECT одновременно.

Также, пожалуйста, обратитесь к разделу Python SQL Lite 3.0 module по разделу 11.13.6 - Управление транзакциями, в котором подробно описано, как можно управлять транзакциями.

Смежные вопросы