On Feb 18, 2013, at 12:10 PM, Juraj Variny <[email protected]> wrote:
> Hello,
>
> I should have expected refresh() to have problem with dirty objects, but if
> it isn't a bug, maybe it should be at least documented.
>
> To explain whole situation and why do I call the refresh() at all: I have
> Account persistent class, with balance property. When doing processing, I'm
> locking the row whenever it is necessary to update it (to not lock more rows
> than necessary), like:
>
> def update(acct,...):
> DBSession.refresh(acct,lockmode='update')
> #update balance, add transaction record,return
>
> The problem is, this function can be called multiple times in one session and
> subsequent refresh calls throw out unsaved changes. So far I have fixed it by
> placing DBSession.flush() calls. But calling flush() in the middle of
> processing implies risk of problems with unmatched constraints (not fully
> fleshed out data). Another idea is to mark already locked objects so that
> refresh() is called only first time in a transaction. Such reentrant behavior
> may be useful to have, what do you think?
if you just want to emit a SELECT .. FOR UPDATE you can just emit that
directly. If you specify with_lockmode() on query(), the get() will emit a
SELECT unconditionally:
session.query(Account).with_lockmode('update').get(my_account.id)
it would be more efficient to not emit this SELECT more times than needed
though this is easy enough to roll on top of a session, like a "lock_object()"
function…can be tracked with events, here's also generalized:
from sqlalchemy import event
from sqlalchemy.orm import Session, object_session, object_mapper
@event.listens_for(Session, "after_begin")
def setup_lock_collection(session, *args):
session._locked = set()
@event.listens_for(Session, "after_commit")
@event.listens_for(Session, "after_rollback")
def clear_lock_collection(session):
session._locked.clear()
def lock_object(obj):
session = object_session(obj)
mapper = object_mapper(my_account)
pk = mapper.primary_key_from_instance(my_account)
if (mapper, pk) not in session._locked:
session.query(mapper).with_lockmode('update').get(pk)
session._locked.add((mapper, pk))
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.