0
在我的CherryPy + Peewee应用程序中,我经常使用以下模式:启动事务,执行操作列表并返回显示结果的页面。如果在任何操作过程中出现问题,我会在日志表中添加一行,然后重定向到显示该行的页面。在失败的事务中执行某些SQL代码
问题是CherryPy中的重定向是通过引发异常来执行的,异常导致一些事务回滚。回滚是我失败的操作所需要的(以及之前的所有操作,即使它们成功了),但这不是我想要的日志记录。
例如用下面的代码,如果用户进入a_page?a=1&b=2&c=3
:
do_this
会发现x != y
,而不是执行show_message
do_this
将在Table1
do_that
会发现x == y
并执行更新一个记录show_message
show_message
会增加一行到第ËMessage
日志表show_message
将为了引发异常重定向到一个页面,会显示消息刚刚登录
因为在事务中,双方就Table1
更新的破例已上升do_this
和记录在show_message
中的消息将被回滚。
如何提交日志表中的行并回滚所有其他更改?
@cherrypy.expose
def a_page(self, a, b, c):
with db.transaction():
self.do_this(a, b)
self.do_that(b, c)
return render('it_worked.html')
def do_this(self, x, y):
if x == y:
self.show_message('Wrong this')
Table1.update(f2=x).where(f1 == y).execute()
def do_that(self, x, y):
if x != y:
self.show_message('Wrong that')
Table1.update(f3=x).where(f1 == z).execute()
def show_message(self, message)
msg = Message.create(msg=message)
raise cherrypy.HTTPRedirect('show_message?id={}'.format(msg.id))
可能是嵌套事务,即保存点。 –
@CL。据我所知,嵌套事务允许你不保存内部操作。我需要相反的东西:我不想保存到现在为止执行的事务,但我想保存最后一个。 – stenci
我找到了一个我不喜欢的解决方案,因为(1)它需要将事务传递给函数,(2)如果存在嵌套事务,则不起作用。这在我的回答如下。请让我知道如果这是一个很好的解决方案,或者我可以做得更好 – stenci