You need to create a new connection for each thread. ZODB provides each connection with a sequential view of transactions (MVCC, multi-view concurrency), so even for reading you need a separate connection. A connection can be reused for consecutive requests in a single thread.
So, for the connection, I would use the pool for the stream provided by ZODB.DB , possibly caching the connection for each request (as pyramid_zodbconn does).
Inside request handlers, you can use the transaction manager as a context manager:
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
Using the transaction.manager object as a context manager ensures that the transaction will be launched upon entry and transferred upon exit without exception, aborted upon exit with exception.
You can also create a context manager to handle the ZODB connection:
from contextlib import contextmanager @contextmanager def zodbconn(db): conn = db.open() yield conn.root() conn.close()
then use this as a context manager along with a transaction manager:
class Example(tornado.web.RequestHandler): def get(self): with zodbconn(db) as root, transaction.manager: res = fn(root) root._p_changed = 1
This context manager accepts the database object and returns the root object, automatically closing the connection when the context terminates again.
source share