我正在使用sqlite3
python模块将批处理作业的结果写入公共.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)
立即执行,他们会抛出异常吗?礼貌地等待其他进程写?有没有更好的方法来做到这一点?
答案 0 :(得分:19)
sqlite
库会在写入数据库时锁定数据库每个进程,并且每个进程都会等待锁定被释放以轮到他们。
然后,在提交时,不需要写入数据库。您正在使用连接作为上下文管理器(好!),因此提交将在您的循环完成并且所有insert
语句都已执行后发生。
如果您的数据库具有唯一性约束,则可能是提交失败,因为一个进程已经添加了另一个进程与之冲突的行。
答案 1 :(得分:4)
如果每个进程都拥有它自己的连接,那么应该没问题。 会发生什么事情,当写入进程将锁定数据库, 所以其他所有进程都会阻止。如果超时,它们将抛出异常 超过等待DB空闲。可以通过connect调用配置超时:
http://docs.python.org/2/library/sqlite3.html#sqlite3.connect
不建议您将数据库文件保存在网络共享中。
更新
您可能还想检查隔离级别:http://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.isolation_level
答案 2 :(得分:1)
好消息是SQLLite库隐式使用一个在执行DML时锁定数据库的事务。这意味着对数据库的其他并发访问将等待,直到执行DML请求通过提交/回滚事务完成。但请注意,多个进程可以同时执行SELECT。
此外,请参阅 11.13.6 - 控制交易部分下的Python SQL Lite 3.0 module,其中详细说明了如何控制交易。