We are using momoko and having following standard setup for async connection to db in tornado application:
class BaseHandler(tornado.web.RequestHandler):
@property
def db(self):
# Create a database connection when a request handler is called
# and store the connection in the application object.
if not hasattr(self.application, 'db'):
self.application.db = momoko.AsyncClient({
'host': 'localhost',
'database': 'momoko',
'user': 'frank',
'password': '',
'min_conn': 1,
'max_conn': 20,
'cleanup_timeout': 10
})
return self.application.db
One day, I found that code like this, will block application:
fail = yield gen.Task(self.db.execute, 'BEGIN; SELECT * FROM non_existing_table; END;')
First idea, that come in head, was:
try:
fail = yield gen.Task(self.db.execute, 'BEGIN; SELECT * FROM non_existing_table; END;')
except:
reconnect()
After some digging on subject, I found that it's better to do something like this:
try:
fail = yield gen.Task(self.db.execute, 'BEGIN; SELECT * FROM non_existing_table; END;')
except:
yield gen.Task(self.db.execute, 'ROLLBACK;')
And finally, after exploring source code of momoko I found, that it's better to use blocking client for transaction.
So BaseHandler transformed into:
class BaseHandler(tornado.web.RequestHandler):
@property
def db(self):
# Create a database connection when a request handler is called
# and store the connection in the application object.
if not hasattr(self.application, 'db'):
self.application.db = momoko.AsyncClient({
'host': 'localhost',
'database': 'momoko',
'user': 'frank',
'password': '',
'min_conn': 1,
'max_conn': 20,
'cleanup_timeout': 10
})
return self.application.db
@property
def bdb(self):
# Create a database connection when a request handler is called
# and store the connection in the application object.
if not hasattr(self.application, 'bdb'):
self.application.bdb = momoko.BlockingClient({
'host': 'localhost',
'database': 'momoko',
'user': 'frank',
'password': '',
'min_conn': 1,
'max_conn': 20,
'cleanup_timeout': 10
})
return self.application.bdb
Now my question... is there any safe way to use transaction in AsyncClient
? Or AsyncClient
is commonly used for read from database, not for writing/updating data there?
I'm working on Momoko 1.0.0 and I just released the first beta. Transactions are one of the new features. Here's my post on the mailinglist: https://groups.google.com/forum/?fromgroups=#!topic/python-tornado/7TpxBQvbHZM
Versions before 1.0.0 don't support transactions, because everytime you run execute
there's a possibility that AsyncClient
will pick a new connection for you and you won't be able to rollback your transaction if anything goes wrong.
I hope this helps a bit. :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.