On Apr 15, 2009, at 8:57 PM, dykang wrote:
> > ah, but since the ORM actually is forced to execute the query anyway, > why not update the object in the identity map with the correct data, > and raise an exception if the current object is dirty? It seems bad > procedure > to be loading an object for update when it's already been modified. I tried an experiment with postgres using serializable isolation, and as it turns out if you've already read the row into the current transaction, then a concurrent transaction modifies the row, then you request select...for update of that same row a second time in the first transaction, it throws a concurrent modification error. so with serializable, the primary isolation mode we have in mind, the use case never comes up. if you're in read committed, it re-reads the latest data from the row from the outside regardless of the usage of FOR UPDATE or not. the PG docs don't say anything about FOR UPDATE changing the isolation characteristics of the SELECT...only the locking (and as you can tell we're using PG, not MySQL, as the baseline for "best" behavior). So to really work with non-serializable isolation and have the ORM return data similar to what the database does, data should always be refreshed with every SELECT, not just those with FOR UPDATE. the autoflush feature, which is generally turned on, prevents the issue of any pending data being overwritten - its always flushed out before the SELECT occurs. This is a lot simpler to implement, that of "populate_existing" on at all times, and would possibly be a flag that folks could use if they decided they are expliclty using non-serializable isolation, would like to have the details of that behavior available to them (i.e. they really want the same row to change its value throughout the transaction), and they're willing to take the performance penalty of re-populating all attributes every time. my reasons for not enabling this by default are that its a performance hit and would be disastrous to use without autoflush. If it were to work in theory without autoflush, it would have to verify attributes as having no pending changes before populating, else raise an error. The performance and complexity overhead of that would be infeasable, not to mention that it's solving a problem that is better solved by choosing a stricter isolation level. Keeping the feature specific to just FOR UPDATE doesn't seem to address the full need of "i want to work in non-serializable isolation", since any SELECT returns fresh data. Maybe the FOR UPDATE case more strongly suggests the feature than the non FOR UPDATE case, but I can't make that decision across the board for all users without a broader discussion - in particular we support many different databases, and who knows what each one does with each kind of isolation they offer. MSSQL can always be counted on to blow up any assumptions you've made. there is an ancient flag on mapper() called "always_refresh" which is the equivalent of "populate_existing" always turned on, but in modern SQLA this would be better suited as a Session flag. The behavior can be achieved in any current SQLA release by using a Query subclass that turns on its populate_existing() flag at construction time. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---
