首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有Tornado的ZODB

带有Tornado的ZODB
EN

Stack Overflow用户
提问于 2013-04-10 03:45:56
回答 1查看 488关注 0票数 4

我有一个用Tornado构建的小型web应用程序,我想在其中使用ZODB进行一些数据存储。根据ZODB的文件,multi-threaded programs are supported, but they should start up a new connection per thread。我想这意味着我必须做一些事情,比如

代码语言:javascript
复制
### 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中抽象该模式的惯用方式是什么?我有一些类似这样的东西

代码语言:javascript
复制
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演示。

也欢迎对该方法进行全面的头部检查。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-10 03:56:57

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

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

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

代码语言:javascript
复制
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时启动,在exit时无异常提交,在exit出现异常时中止。

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

代码语言:javascript
复制
from contextlib import contextmanager

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

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

代码语言:javascript
复制
class Example(tornado.web.RequestHandler):
    def get(self):
        with zodbconn(db) as root, transaction.manager:
            res = fn(root)
            root._p_changed = 1

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15911121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档