繁体   English   中英

在同一全局python应用程序中的多个模块中使用SQLite3时,最佳方法是什么?

[英]What is the best approach when using SQLite3 from multiple module in the same global python application?

我目前正在python 2.7中开发一个Web应用程序,该应用程序是基于几个模块构建的,这些模块导入了我的主要python应用程序并从中调用函数。 几乎所有这些模块都打开了与同一SQLite3数据库的连接,其中一些模块不时进行更新或插入表中。

有时,当两个或多个模块尝试同时更新数据库时,出现数据库锁定错误。 那使我开始质疑自己...

我是否一直在做错误的事情来打开和关闭与数据库的连接,还是应该在程序开始时将其打开并在结束时将其关闭?

在这种情况下,在所有模块之间共享此连接的更好方法是什么?

谢谢你的帮助!

Sqlite并非旨在处理并发访问(尤其是写访问)。

保持连接打开通常是一个好主意,但这可能取决于使用频率。

如果可以从多个线程进行数据库访问,则用相同的LockRLock封装所有线程很有用。

例如,您可以为此编写一个上下文管理器:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM