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
은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