14

我正在使用sqlite3python 模块将批处理作业的结果写入一个公共.db文件。我选择 SQLite 是因为多个进程可能会尝试同时编写,据我了解,SQLite 应该很好地处理这个问题。我不确定的是当多个进程完成并尝试同时写入时会发生什么。所以如果有几个看起来像这样的进程

conn = connect('test.db')

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

立即执行,他们会抛出异常吗?礼貌地等待其他进程写入?有没有更好的方法来做到这一点?

4

3 回答 3

26

当写入数据库时​​,sqlite库将锁定每个进程的数据库,每个进程将等待锁被释放以轮到它们。

然而,直到提交时间才需要写入数据库。您将连接用作上下文管理器(很好!),因此在您的循环完成并且所有insert语句都已执行后进行提交。

如果您的数据库具有唯一性约束,则提交失败可能是因为一个进程已经添加了与另一个进程冲突的行。

于 2013-08-13T10:57:10.047 回答
6

如果每个进程都有自己的连接,那应该没问题。会发生的是,在写入进程时会锁定数据库,因此所有其他进程都会阻塞。如果超过等待数据库空闲的超时,它们将抛出异常。超时时间可以通过 connect 调用来配置:

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

不建议您将数据库文件放在网络共享中。

更新:

您可能还想检查隔离级别:http ://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.isolation_level

于 2013-08-13T10:57:59.057 回答
1

好消息是 SQLLite 库在执行 DML 时隐式使用锁定数据库的事务。这意味着对数据库的其他并发访问将等到正在执行的 DML 请求通过提交/回滚事务完成。但是请注意,多个进程可以同时执行 SELECT。

此外,请参阅第11.13.6 节 - 控制事务下的Python SQL Lite 3.0 模块,其中详细说明了如何控制事务。

于 2013-08-13T11:27:02.817 回答