ツイストのadbapiモジュールでトランザクションがどのように機能するかを理解しようとしています。現在、INSERTステートメントとUPDATEステートメントを実行するためにrunOperation()を使用しています。以下にリンクするドキュメントでは、トランザクションをサポートしているように見えますが、私が望む方法ではないようです。次にいくつかのサンプルコードを示します(Cyclone Webサーバー内で実行されていますが、関係がないことを願っています)。
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")
この場合、すべてがロールバックされるという効果が得られますが、ご覧のとおり、コードはまったく異なります。各コールバックが1つのクエリを実行するコールバックをチェーン化する代わりに、1つの大きなメソッドですべてを実行しているだけです。
トランザクションをサポートするためにこれを行う必要がある方法はありますか?
ドキュメントへのリンクは次のとおりです。
http://twistedmatrix.com/documents/current/core/howto/rdbms.html