>
> when you say query(Class).filter(<criterion>).one(), that always emits SQL. 
>  It's an open-ended query, and SQLalhcemy doesn't know that s2c1 is the 
> object which corresponds to the SQL you're about to emit.   When the row 
> comes back, it then extracts the primary key from the incoming row, 
> determines that identity is already in the identity map and is unexpired, 
> and the row is skipped
>

It ignores new data?  I'm clearly going to need to be even more careful 
about this when I expect 'read committed' behaviour from the database.
 

> (that's the disconnect here - incoming rows are not used if the existing 
> identity exists and is unexpired).
>

Is there a global, or per session or something, way to change this 
ignore-new-data behavior (aside from manually expiring objects prior to 
querying for data?).  Or even more brutal, can the identity map feature be 
turned off altogether on a per session basis?

For those cases when 'read committed' and the associated 
transaction-transaction contamination is actually the desired behavior, 
having to manually tell SQLAlchemy to expire everything all the time so that 
it doesn't ignore new incoming data is quite an extra layer to worry about 
on top of the the already treacherous concurrency issues around 'read 
committed'.  I always knew the identity map was something to be wary of with 
concurrency since it is effectively another layer of isolation on top of 
what the DB is set up to do, but didn't consider the fact that new data that 
is read would be ignored.

>From earlier you said:

 

> If a concurrent transaction were to come in from underneath and change "1" 
> to "222" while you were still in your ongoing operation, you might be pretty 
> upset
>

But I shouldn't be!  That is *exactly* how 'read committed' is supposed to 
behave.  If I don't want that, I should be setting "repeatable read" or 
"serializable".   Although I guess it's true that most developers don't 
quite know about transaction isolation levels (I sure didn't until fairly 
recently) and might be upset with SQLAlchemy at the first layer, if it did 
happen to them...

if OTOH you had said query(Class).get(pk), that would pull from the identity 
> map directly and not even hit the DB in this case.
>

I usually end up using one() and never use get()... I'll look at using get() 
now, as frequently my one() criteria was only on the PK.  And I'll obviously 
be wary of isolation issues with this.  Usually having the identity map is 
awesome.

My main issue was/is that I saw SQL being emitted, was expecting 'read 
committed' behaviour, and didn't get it.  Now I completely know why... 
thanks again.

Russ

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/98kZ3oQ-jsUJ.
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