我正试图弄清楚事务在twisted的adbapi模块中是如何工作的。我目前正在使用runOperation()来执行INSERT和UPDATE语句。我将在下面链接到该文档,它看起来支持事务,但似乎并不像我希望的那样。以下是一些示例代码(它在旋风网络服务器中运行,但希望与此无关):
class OperationHandler(cyclone.web.RequestHandler):
@cyclone.web.asynchronous
def get(self, *args, **kwargs):
d = conn.runOperation("INSERT INTO Table1 (Field1, Field2) VALUES ('a', 'b')")
d.addCallback(self.next1)
def next1(self, rows):
d = conn.runOperation("UPDATE Table1 SET Field1 = 'c'")
d.addCallback(self.next2)
def next2(self, rows):
raise Exception("rollback")
self.finish("done")
在这种情况下,即使在上一次回调中引发了异常,INSERT和UPDATE语句都会执行。不是我想要的。
我试着转换为使用runInteraction()方法,但我不确定我做得是否正确。
class InteractionHandler(cyclone.web.RequestHandler):
@cyclone.web.asynchronous
def get(self, *args, **kwargs):
d = conn.runInteraction(self.someTransaction)
d.addCallback(self.done)
def someTransaction(self, txn):
txn.execute("INSERT INTO Table1 (Field1, Field2) VALUES ('a', 'b')")
txn.execute("UPDATE Table1 SET Field1 = 'c'")
txn.execute("UPDATE Table1 SET Field1 = 'd'")
raise Exception("rollback")
def done(self, rows):
print rows
self.finish("done")
在这种情况下,我得到了我想要的效果,即所有内容都被回滚,但正如您所看到的,代码完全不同。我只是在一个大方法中执行所有内容,而不是将回调链接在一起,每个回调运行一个查询。
为了支持交易,是否必须这样做?
以下是文档链接:
http://twistedmatrix.com/documents/current/core/howto/rdbms.html
http://twistedmatrix.com/documents/12.0.0/api/twisted.enterprise.adbapi.ConnectionPool.html#runInteraction
是。基于runInteraction
的重写是正确的。