ZODB与龙卷风

时间:2013-04-09 19:45:56

标签: python tornado zodb

我有一个使用Tornado构建的小型网络应用,我想使用ZODB进行一些数据存储。根据ZODB文档,multi-threaded programs are supported, but they should start up a new connection per thread。我认为这意味着我必须做一些像

这样的事情
### On startup
dbFilename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Data.fs")
db = DB(FileStorage(dbFilename))

### Example handler
class Example(tornado.web.RequestHandler):
    def get(self):
        try:
            conn = db.open()
            root = conn.root()
            ### do stuff with root here
            root._p_changed = 1  ## Include these lines for writes
            transaction.commit() ## on sub-elements
        finally:
            conn.close()

首先,对于所有与数据库交互的处理程序还是仅进行写入的处理程序,新连接是否仍然是必需的?在启动时启动一个连接并将其用于我的所有读取是否合理,然后只在我需要编写内容时才进行上述连接歌曲和舞蹈?

其次,在Python中抽象该模式的惯用方法是什么?我有类似

的东西
def withDB(fn):
    try:
        conn = db.open()
        root = conn.root()
        res = fn(root)
        root._p_changed = 1
        transaction.commit()
        return res
    finally:
        conn.close()

def delete(formName):
    def local(root):
        ### do stuff with root here
    return withDB(local)
记住,但那可能是我的Lisp表现。

也欢迎对这种方法进行一般性的核查。

1 个答案:

答案 0 :(得分:4)

您需要为每个线程创建一个新连接。 ZODB为每个连接提供一致的每事务视图(MVCC,多视图并发控制),因此即使是读取,您也需要单独的连接。该连接可以在一个线程中重复用于顺序请求。

因此,对于连接,我将使用ZODB.DB提供的每线程池,可能会缓存每个请求的连接(如pyramid_zodbconn所做)。

在请求处理程序中,您可以将事务管理器用作上下文管理器:

class Example(tornado.web.RequestHandler):
    def get(self):
        connection = some_connection_pool.get_connection()
        with transaction.manager:
            root = conn.root()
            res = fn(root)
            root._p_changed = 1

使用transaction.manager对象作为上下文管理器可确保事务在enter时启动,并在退出时无异常地提交,在退出时中止,但异常。

您也可以创建一个上下文管理器来处理ZODB连接:

from contextlib import contextmanager

@contextmanager
def zodbconn(db):
    conn = db.open()
    yield conn.root()
    conn.close()

然后将其与事务管理器一起用作上下文管理器:

class Example(tornado.web.RequestHandler):
    def get(self):
        with zodbconn(db) as root, transaction.manager:
            res = fn(root)
            root._p_changed = 1

此上下文管理器获取数据库对象,并返回根对象,在再次退出上下文时自动关闭连接。

相关问题