Filip, Thanks for your very informative explanations and ideas. I will be studying it closely.
Thanks, Michael Filip Wasilewski wrote: > Hi Michael, > > On Jan 30, 6:25 pm, Michael Hipp <[EMAIL PROTECTED]> wrote: >> James Bennett wrote: >>> On Jan 30, 2008 9:18 AM, Michael Hipp <[EMAIL PROTECTED]> wrote: >>>> Does Django have any built-in way to handle or prevent simultaneous, >>>> incompatible edits to a database record? >>> No, that's what your database's concurrency handling is for. >> Ok, I probably didn't explain well enough... >> >> I'm using PostgreSQL so concurrency isn't a problem. >> >> What is a problem is that user A loads a record and begins making changes. >> Then user B loads the same record and begins making different changes. One of >> them saves it first followed by the other and the only trace that's left is >> what was saved by the one that got there last. >> >> No real issue at the database level. PG doesn't care. But possibly a very big >> issue at the application level (especially if each of the saves also modified >> related tables based on the different inputs of each user) and the >> application >> level of each could not know about the other so opportunities to prevent this >> disaster are few at the app level. > > The way in which you handle the application-level transactions that > span across a set of requests it entirely up to you :-) Thinking of > typical scenarios you could either synchronize data in real time > (something like google docs), synchronize on save (some kind of diff > and merge), warn users before they start editing a record which is > already opened for edit by another user (like in MoinMoin) or just > overwrite or ignore changes (like in all bad-user-experience-apps). > > > The third option seems quite reasonable and its also not very hard to > implement. All what you will need is a (generic) registry that will > hold information about checked out objects (rows, records, documents - > whatever the naming convention is) and some locking logic. > > The registry could be simply a model with three fields: [generic] > model foreign key, user foreign key, and a checkout time, with unique > constraint on the model foreign key. If you don't need to track > different models then a "classic" foreign key instead of a generic > contenttypes one should be just fine. > > The functions that will provide a locking interface should be atomic > (that's the place where the database level transactions come into > play). A typical pattern is to have at least an acquire (lock) and a > release (unlock) routines, plus a couple of additional helpers for the > typical use cases: > > * acquire_lock(object, user) - creates an entry/replaces expired one > in the registry, allows for re-entrant locking (the same lock can be > obtained many times by the user that already possess it without > raising an error), raises an exception if an object is already locked > by another user and the lock period hasn't expired. > > * release_lock(object, user) - removes lock from the registry > > * is_locked(object, user) - checks if a valid object lock entry exists > > Cyclic removal of expired entries from the registry should not be > necessary unless you count for every byte or need to reduce number of > queries (in a typical case they will consume considerably less space > than the other models' data). > > After setting this up you should have a pretty robust mechanism for > controlling parallel access attempts to database records/objects. Just > lock the object on edit, release the lock on save and issue a warning > on concurrent edit attempts. > >> I've seen some table layouts that included a column like "last_edit_serial" >> so >> that a steadily incrementing serial could provide a hint to the app level >> that >> something had changed since the record was loaded. > > Only when you want to notify someone that his effort has just been > cancelled because someone else has corrected a typo in the meantime > and saving changes is not permitted ;-) > >> But I don't see Django adding any such columns and was wondering if a >> different mechanism was in effect. Or if some other technique was widely used >> among Django users. > > What makes me wonder even more is the fact how fantastically people > seem to get away without all this stuff :-) > > > Hope that helps, > > f > > -- > http://filipwasilewski.pl > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---