私の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
は、1行Table1
上の取引では、更新の両方がで作られている間に例外が上がってきたので、順番に例外が発生しますshow_message
電子Message
ログテーブルは、ちょうど
をログに記録されたメッセージが表示されますそのページにリダイレクトします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