gpt4 book ai didi

transactions - 扭曲的 adbapi 事务何时真正提交?

转载 作者:行者123 更新时间:2023-12-04 03:58:28 25 4
gpt4 key购买 nike

我在旋风网络服务器中使用 adbapi。首先,我的处理程序将一些内容写入 SQL 数据库,然后向另一个 Web 服务器发出 HTTP 请求。如果该 HTTP 请求失败,我希望数据库事务回滚。但是,我没有得到那种效果。查看文档,它说

The function will be called in the thread with a twisted.enterprise.adbapi.Transaction, which basically mimics a DB-API cursor. In all cases a database transaction will be commited after your database usage is finished, unless an exception is raised in which case it will be rolled back.



这并不像我想要的那样精确。我的“数据库使用完成”究竟是在什么时候?那是在调用处理程序的 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 服务器?

最佳答案

好吧,我使用同步调用重新实现了代码,它似乎可以正常工作。查看 runInteraction() 方法的文档,它更清楚一点:

def runInteraction(self, interaction, *args, **kw):

Interact with the database and return the result.The 'interaction' is a callable object which will be executed in a thread using a pooled connection. It will be passed an Transaction object as an argument (whose interface is identical to that of the database cursor for your DB-API module of choice), and its results will be returned as a Deferred. If running the method raises an exception, the transaction will be rolled back. If the method returns a value, the transaction will be committed.

关于transactions - 扭曲的 adbapi 事务何时真正提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12592481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com