我在旋風web服務器中使用adbapi。首先,我的處理程序將一些內容寫入SQL數據庫,然後對另一個Web服務器發出HTTP請求。如果該HTTP請求失敗,我希望數據庫事務回滾。但是,我沒有得到那種效果。綜觀文檔,它說什麼時候扭曲的adbapi事務實際上被提交?
的功能將與 twisted.enterprise.adbapi.Transaction,基本上模仿了DB-API 光標線程調用。在所有情況下,在您的數據庫使用完成後,數據庫事務將在 之後被提交,除非在 中引發了異常,否則它將被回滾。
這並不完全如我所願。到底什麼時候我的「數據庫使用已完成」?那是什麼時候調用處理程序的self.finish()方法?傳入ConnectionPool.runInteraction()的方法完成後?
這裏是我的代碼
class AccountCreationHandler(BaseRequestHandler):
@cyclone.web.asynchronous
def post(self, accessKey, *args, **kwargs):
try:
d = connPool.runInteraction(self.saveStuffToDatabase)
d.addCallback(self.callWebServer)
d.addCallback(self.formatResult)
d.addErrback(self.handleFailure)
except Exception, e:
self.handleException(e)
def saveStuffToDatabase(self, txn):
txn.execute("INSERT INTO Table1 (f1) VALUES ('v1')")
def callWebServer(self):
agent = Agent(reactor)
hdrs = Headers({ "Content-type": ["application/json"] })
values = json.dumps({ "someField": 123 })
body = SimpleProducer(values)
url = "http://somewebserver.com"
d = agent.request("POST", url, hdrs, body)
d.addCallback(self.handleWebResponse)
return d
def handleWebResponse(self, response):
if response.code == 200:
d = Deferred()
receiver = SimpleReceiver(d)
response.deliverBody(receiver)
d.addCallback(self.saveWebServerResults)
return d
else:
raise Exception("web server failed with http status code %d" % response.code)
def saveWebServerResults(self, body):
self.results = body
def formatResult(self):
self.finish(self.results)
class SimpleProducer(object):
implements(IBodyProducer)
def __init__(self, body):
self.body = body
self.length = len(body)
def startProducing(self, consumer):
consumer.write(self.body)
return succeed(None)
def pauseProducing(self):
pass
def stopProducing(self):
pass
class SimpleReceiver(Protocol):
def __init__(self, d):
self.buf = ''
self.d = d
def dataReceived(self, data):
self.buf += data
def connectionLost(self, reason):
if type(reason.value) == ResponseDone:
self.d.callback(self.buf)
else:
self.d.errback(reason)
在Web服務器拋出一個錯誤或者連接超時或基本上如果代碼不會越過saveStuffToDatabase方法的情況下,沒有被回滾時出錯發生。
我猜測這意味着事務是在傳遞給ConnectionPool.runInteraction()的方法已經完成而沒有拋出異常時提交的。如果是這樣的話,那麼我想我將不得不把所有東西,包括在saveStuffToDatabase()內同步調用Web服務器?
對此沒有想法? – d512