[英]What is the best approach when using SQLite3 from multiple module in the same global python application?
我目前正在python 2.7中开发一个Web应用程序,该应用程序是基于几个模块构建的,这些模块导入了我的主要python应用程序并从中调用函数。 几乎所有这些模块都打开了与同一SQLite3数据库的连接,其中一些模块不时进行更新或插入表中。
有时,当两个或多个模块尝试同时更新数据库时,出现数据库锁定错误。 那使我开始质疑自己...
我是否一直在做错误的事情来打开和关闭与数据库的连接,还是应该在程序开始时将其打开并在结束时将其关闭?
在这种情况下,在所有模块之间共享此连接的更好方法是什么?
谢谢你的帮助!
Sqlite并非旨在处理并发访问(尤其是写访问)。
保持连接打开通常是一个好主意,但这可能取决于使用频率。
如果可以从多个线程进行数据库访问,则用相同的Lock
或RLock
封装所有线程很有用。
例如,您可以为此编写一个上下文管理器:
class ConnectionHolder:
def __init__(self, connection):
self.connection = connection
self.lock = RLock()
def __enter__(self):
self.lock.acquire()
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
self.lock.release()
用法:
conn_holder = ConnectionHolder(connection) #Global or in an app-wide accessible object
...
with conn_holder as conn:
conn.<do something>
...
<Don't do anything more with conn>
应使用Lock
还是RLock
取决于使用情况。 Lock
可能会稍微更有效(但通常这并不重要),但是RLock
允许使用例如
def getSomeData():
with conn_holder as conn:
<Retrieve data over conn and return it>
def changeSomeData():
with conn_holder as conn:
data = getSomeData()
<Modify retrieved data and update database (saved against concurrent
changes by the "with")>
在这里你可以调用getSomeData()
直接或间接地通过changeSomeData()
(嗯,根据数据库模式(WAL模式),您不需要getSomeData()
的锁,但是可能需要更复杂的情况。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.