On May 10, 8:12 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On May 10, 2011, at 12:48 PM, Luper Rouch wrote:
>
>
>
>
>
>
>
>
>
> > I often run into problems when working with SA's events.
> > MapperExtension's methods are called in the middle of a flush, and so
> > there are things to take care of. For example:
>
> >  * if you add new objects to the session, or do an update during an
> > event, you'll have to call session.flush() a second time for them to
> > be actually inserted or updated (and you can't call flush() within the
> > event since you're in the middle of a flush). There is a workaround
> > for this issue, you use a SessionExtension that looks for dirty
> > objects in its after_flush_postexec() method, and call flush() a
> > second time if there is any [1].
>
> >  * if an error occurs during an event (e.g. a database timeout), you
> > can't handle it within the event with a rollback or else you'll get an
> > "InvalidRequestError: The transaction is inactive due to a rollback in
> > a subtransaction. Issue rollback() to cancel the transaction." error
> > on the next usage of the transaction [2].
>
> > While the first problem just involves a quick hack (which you still
> > have to figure out), the second is more annoying and involves coupling
> > (you have to know that the particular table you are flushing triggers
> > events and needs special error handling).
>
> > I think it would make sense to add new events triggered *outside* of
> > the flush mechanism. For example the order of operations for an update
> > would look something like this :
>
> > outer_before_update()
> > [begin]
> > before_update()
> > [emit SQL update]
> > after_update()
> > [commit]
> > outer_after_update()
>
> > This way you would code normally in events, as you do in the rest of
> > your code, without taking care of special rules.
>
> > Maybe MapperExtension is not the right place to add these kind of
> > events (as I see it, it's more a tool to extend the API than a day to
> > day tool to work with events), and something like MapperEvents should
> > be created instead ?
>
> You should be using SessionExtension for most of these use cases.   As the 
> docs state you can't change the flush plan inside of 
> before_update()/before_insert() kinds of events, you do that in 
> before_flush().   There's a number of examples in examples/ and on the wiki 
> which illustrate this usage.   Also you should probably be moving up to 0.7 
> where the events system has been vastly improved.  In particular there is an 
> ample space for us to add new functionality to listen() that will allow the 
> "check the dirty list" part of session event handling, and similar, to be 
> automated by SQLAlchemy itself.
>
> The session doesn't support the "try something, it fails, rollback, keep 
> doing the flush" kind of pattern.   There's info in the FAQ regarding the 
> rationale here.  You'll have to approach that in a different way, typically 
> using begin_nested() to work with SAVEPOINT and working outside the scope of 
> flush().    This is something that should be dealt with at the point of 
> integration with your app and not within the Session itself (or at least, a 
> custom Session subclass).   A "database timeout" though is outside the scope 
> of all of that - if you lose your connection, your transaction is gone.  You 
> need to run the whole operation again from the start.  Typically its better 
> to prevent timeouts from the start (depends on why you think you'd be getting 
> timeouts) or to take an optimistic approach (i.e. failures are rare, they 
> happen, the app recovers on the next try).    
>

I agree, when a timeout happens, we display an error message and tell
the user its last operation failed. The point is not recovering from
the failure automatically, but avoiding the "The transaction is
inactive due to a rollback in a subtransaction. Issue rollback() to
cancel the transaction" error, which happens on all subsequent queries.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to