[Zope-DB] Question: detecting aborted transactions

Matthew T. Kromer matt at bane.mi.org
Tue Mar 16 15:58:17 EST 2004


jelle wrote:

>Hello Chris,
>
>My workflow-type app does 3-20 sql statments per web page. Normally, under 
>low load situations, a transaction begins with the first sql statement and 
>commits upon completion of the thread. Under high load, Postgresql 
>occasionally aborts a statement with the message "could not serialize 
>access due to concurrent update" which causes the Zope mechanism to 
>silently rollback the transaction. The very next sql statement within the 
>same Zope thread starts a new transaction resulting in an funky data.
>
>Perhaps I can solve the problem by (1) committing after each 
>statement, and (2) detecting rollbacks and resending the offending sql 
>statement after a short delay.
>
>The questions: is that possible within ZSQL and if so how?
>
>
>  
>

You should not attempt to commit data directly!  Instead, you want to 
let the database connection object commit for you.  If you commit 
directly you are interfering with Zope's built in transactional 
boundaries.  The transaction manager in Zope is one of the most clever 
things it has -- let it work on your behalf!

Now, maybe you ARE doing this, and I'm misinterpreting what you're saying.

When you say "commits upon completion of the thread" is where I get 
confused.  Zope threads really don't tend to just spring into being and 
then complete, instead the medusa component (the web server part) queues 
up requests for worker threads which rendezvous to pick up work.  Each 
worker thread hangs around afterwards rather than dissapearing -- it 
just goes back in line to pick up more work.

When the worker thread hands the results back over to medusa at the end 
of the request, it commits the Zope transaction.  This is a two phase 
commit (tpc_vote comes first) and your database connection object SHOULD 
have registererd itself with the transaction manager to do a postgres 
commit during the vote phase.   Depending on the semantics of your 
adapter (none of them do two phase to my knowledge) it can do a one or 
two phase commit itself.  The only time this becomes important is those 
rare circumstances like you describe when the commit itself aborts. 

If the Zope transaction aborts during the vote phase (which is allowed) 
the transaction is retried or aborted (well, it depends on what error it 
raises -- database adapters probably don't raise ConflictErrors which 
would be what causes the request to be retried).  If the commit error 
occurs AFTER the vote phase bad things happen, tending to cause Zope 
some grief.

What you *probably* want to look at doing is tweaking the posgresql 
adapter to see what error types it is throwing, and if you're getting a 
serialization error turn that into a ConflictError so that Zope retries 
the request for you.




More information about the Zope-DB mailing list