De oplossing is reeds gegeven, maak gebruik van timestamps.
Ik zal in het kort uitleggen waarom andere oplossingen minder elegant zijn.
Whoami heeft het juist als hij zegt dat indien je niets doet en gewoon een update statement naar buiten stuurt (met in where clausule de primary key) met de nieuwe veldwaarden, je het risico loopt dat aanpassingen van andere gebruikers overschreven worden. Dat is dus wat je zeker niet moet doen.
Volgende voorstel heeft ook zijn nadelen : In een table bijhouden welke open zijn (nesQuick). Als een gebruiker gaat pauzeren, kan gedurende die pauze niemand dat record updaten (of zelfs benaderen bij een exclusive lock!) en dat wil je uiteraard voorkomen. Hetzelfde geldt voor de row te locken. Binnen een transactie moet je nooit ofte nimmer een gebruikersinteractie toelaten (in dit geval wijzigen van data), want dat houdt de zaak onnodig op en de kans is reëel dat je andere gebruikers dwarsligt.
In een tabel bijhouden welke rijen van een tabel gelockt zijn door andere gebruiikers, is ook niet zo voordelig als men denkt. Indien de connectie verloren gaat (bijvoorbeeld doordat het netwerk uitvalt, of de gebruiker de applicatie afschiet of iets anders misgaat, worden die waarden nooit meer veranderd) hou je rijen vast, terwijl niemand daar daadwerkelijk iets aan het veranderen is. Voor die gevallen zul je zelfs een vrijgeefmechanisme moeten bouwen, want anders blijven die records tot in den eeuwigheid gelockt (Amen)
Bovenbeschreven oplossingen die het liefst voorkomen moeten worden, worden in de DB wereld beschreven als het pessimistic locking principe. Oke, het is een betere wijze dan helemaal geen locking principe toe te passen en gewoon maar alles lukraak te overschrijven, in de hoop dat niemand dat record reeds heeft aangepast. Maar dit pessimistic lockingprincipe heeft zo zijn nadelen (O.a. onnodig veel locks, waardoor het gevaar groter wordt dat andere gebruikers geblockt worden).
Bij pessimistic locking wordt er, om te voorkomen dat anderen dat record kunnen veranderen, een lock (mechanisme) geactiveerd, alvorens men daadwerkelijk gaat updaten. Echter, door het pessimistic locking mechanisme toe te passen, zorg je er dus voor dat andere gebruikers gedurende de locktijd dat record niet kunnen wijzigen, proberen ze het toch, dan worden zij geblockt, net zolang totdat jij je update weer vrijgeeft (Leuk als je even een uurtje pauze neemt).
En het lullige is, dat indien een ander dat record dan toch daarna update met in de where clausule alleen de primary key, dan ook het gevaar bestaat dat reeds gewijzigde gegevens overschreven worden.
Oke, er zijn mensen die zeggen dat ze in de where clausule alle veranderde velden (of alle) zetten en checken of de waarde nog gelijk is aan de oude waarde, maar dan moet je de oude waarden dus wel nog weten en bovendien hebben we dan geeneens een pessimistic lockingmechanisme nodig! (Je zult immers altijd moeten nagaan of er dan wel iets is geupdate, dus waarom lock je de zaak dan onnodig voor anderen)
Enfin, het komt er dus op neer dat je onnodige locks zoveel mogelijk wil voorkomen in een multi-user omgeving (100% voorkomen is in praktijk onmogelijk), want in het ergste geval kan dit weer leiden tot blocking of zelfs tot deadlock situaties!!
Wat is dan wel een goed mechanisme? Optimistic locking. Dat kan op twee manieren, ofwel je test tijdens de update of alle veranderde velden nog steeds de oude waarde hebben, ofwel je maakt gebruik van timestamps.
Persoonlijk ben ik er voorstander van timestamps te gebruiken. Een timestamp attribuut heeft namelijk de eigenschap van waarde te veranderen, zodra het record wordt gewijzigd. De where claulsule van het update statement moet bij optimistic locking toch al uitgebreid worden, dus het minste werk is dan een test te doen met een timestamp (1 extra check, t.o.v. n extra checks). uiteraard moet je dan wel je tabel voorzien van zo'n timestampattribuut.
Hoe gaat het in zijn werk? Tijdens het ophalen van je data haal je in dezelfde query ook per record het timestamp attribuut op. Indien je het mooi wil maken, kun je voordat je gaat wijzigen controleren of de timestamp van het te wijzigen record nog dezelfde waarde heeft. Is dat zo, dan heeft niemand dat record aangepast, zo nee dan kun je alsnog de laatste stand van zaken ophalen (inclusief timestamp attribuut) voor je gaat wijzigen.
Tijdens het bewaren, voeg je in de where clausule van je SQL statement de test van het timestamp attribuut toe (where primary_key = datte and timestamp_attribuut = ditte). Mocht er niets geupdate worden, dan weet je dat een ander reeds wijzigingen heeft aangebracht. Je zult dan in geen geval wijzigingen van andere gebruikers overschrijven en ook gebruikers niet onnodig blocken.