I am trying to figure out how transactions work in a twisted adbapi module. I am currently using runOperation () to execute INSERT and UPDATE statements. The documentation that I refer to below suggests that it supports transactions, but it does not seem to me the way I would like. Here is a sample code (running it inside the cyclone web server, but hopefully this is not relevant):
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")
In this case, even if an exception occurs in the last callback, both the INSERT and UPDATE statements are executed. Not what I want.
I tried converting to use the runInteraction () method, but I'm not sure if I am doing it right.
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")
In this case, I get the effect that I want, in which everything is rolled back, but, as you can see, the code is completely different. Instead of linking the callbacks together when each callback makes one request, I just execute everything in one big method.
How to do this to support transactions?
Here are the links to the documentation:
http://twistedmatrix.com/documents/current/core/howto/rdbms.html
http://twistedmatrix.com/documents/12.0.0/api/twisted.enterprise.adbapi.ConnectionPool.html#runInteraction