Record lock
Aangezien ik een multiuser applicatie heb...
Ik zou graag een melding willen geven (geen toegang willen geven) als iemand een zelfde record - in dezelfde database - wil gaan wijzigen.
Moet ik wellicht zelf een vlaggetje zetten als iemand een record aan het wijzigen is, of zit dat al ergens in de database (MYSQL).
Bij voorbaat dank !
Wat wil je locken en met welk doel?
Quote:
als iemand een record aan het wijzigen is
Hij wil ervoor zorgen dat wanneer iemand een record ophaald om te wijzigen, een tweede persoon niet hetzelfde record kan opvragen en wijzigen.
Dit voorkomt dus dat 2 of meer mensen tegelijk hetzelfe record gaan wijzigen. hetzelfde als bijvoorbeeld in Excel 2 mensen hetzelfde document openen, dan zal de tweede een 'Alleen lezen' versie krijgen.
@Paco,
Dan zul je tijdens een select ook een insert moeten maken waar je een veld locked update met een 1 of een 0.
Daarna zul je ook bij elke select moeten controleren of het locked veld van dat record op 0 staat.
Staat het lock veld op 1 dan geef je een melding dat het record momenteel in gebruik is, is het 0 dan kan hij bewerkt worden. Maak dan wel bij elke select een insert zodat die 0 naar een 1 wordt gezet, en bij een update van het record ook de 1 weer naar een 0 gezet wordt zodat het record weer vrij komt.
Toevoeging op 13/06/2013 16:47:37:
Dus wat je nodig hebt is:
- Een extra veld in je tabel 'locked' waar je een 0 of een 1 in schrijft (standaard 0)
- Een select query waar je het record ophaald ook gelijk een insert query waar je van het opgehaalde record 'locked' op 1 zet.
- Bij de update query weer het 'locked' veld op 0 gezet wordt en het record weer voor andere mensen toegankelijk is.
- Bij elke select query op dat tabel een check doen of 'locked' 0 is, zoniet dan mag het record niet opgehaald worden.
Gewijzigd op 13/06/2013 16:48:57 door Chris PHP
Is het eigenlijk gebruikelijk om records te locken?
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Oké, maar dan moet je dus eigenlijk bij iedere tabel die door meerdere personen gewijzigd kan worden een veld "locked" toevoegen? Is dat de oplossing?
Let natuurlijk wel dat een optie zoals ik voorstel nooit fail-proof zal zijn! Het kan zo zijn dat records op locked blijven staan als mensen bijvoorbeeld een record ophalen en zonder een update query te draaien gewoon het venster sluiten.
Dan zal 'locked' op 1 blijven staan, en kan niemand meer bij dat record.
Gewijzigd op 13/06/2013 17:04:00 door Chris PHP
Hehe, oke :)
Chris NVT op 13/06/2013 16:59:59:
@Ozzie,
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Volgens mij kan je veel beter gaan werken met een archief functie dan met een dergelijke lock. Geheid dat dat heel veel problemen gaat opleveren. Want wat als iemand eeen record ophaalt en vervolgens zijn pc uitzet. Blijft die er in staan en kan niemand er meer bij.
Daarnaast wat is het verschil tussen mensen die in feite tegelijkertijd de verandering uitvoeren, of die het vlak achter elkaar uitvoeren? De database ziet gewoon twee veranderingen vlak achter elkaar en zal de eerst de 1 en dan de ander uitvoeren. Ongeacht wat er op dat moment in het record staat.
Als je gewoon voor elke verandering het record eerst naar een archief tabel stuurt (inclusief archiveringstijd en gebruiker die het doet) heb je een wat mij betreft veel betere oplossing. Dan heb je namelijk ook nog de mogelijkheid om terug te gaan naar een oudere versie, of in elk geval kan je zien wie wat veranderd heeft.
Zo'n lock zou ik echt niet voor gaan.
Erwin, dankjewel voor je toelichting. Ik heb in Joomla volgens mij wel eens iets vergelijkbaars gezien met zo'n lock. Stel dat je bijv. een nieuwsartikel wil aanpassen. Hetkan dan zijn het "op slot" zit. Echter, door op het slotje te klikken, kun je het gewoon weer unlocken. Op die manier heeft het eigenlijk meer een soort "waarschuwingsfunctie". Hé, let op... iemand is dit nieuwsbericht aan het bewerken. Echter, als je zeker weet dat niemand er mee bezig is, kun je het bericht gewoon weer unlocken.
Het doel ervan is dat mensen niet tegelijk 1 record wijzigen. En dan gaat het hier niet om een adresje wijzigen of iets in die richting maar bijvoorbeeld een stuk tekst aanpassen.
Dan ga je krijgen dat er misschien verschillen of misverstanden onstaan, en dus niet het gewenste resultaat opleveren. Daarom heeft Excel ook de 'Alleen lezen' functie erin zitten, zodat je geen gegevens gaat wijzigen die iemand anders misschien op dat moment ook aan het wijzigen is.
Het is niet zo dat MySQL hier niet mee overweg kan, maar dat mensen fouten maken ;-)
Tevens kun je het lock probleem op verschillende manieren oplossen.
- Je kunt een cronjob maken die standaard elke dag om 18:00 draait en alle records weer op 0 zet.
- Je kunt er een optie in maken dat medewerkers een record zelf kunnen unlocken maar dat ze wel zien dat het record dus in gebruik is
- Je kunt een 'admin' account maken die alle records mag openen ongeacht of ze 'locked' zijn of niet.
- Je kunt bijhouden in een sessie welke record_id's de gebruiker heeft geopent, en deze tijdens het uitloggen weer op 0 zet.
Er zijn mogelijkheden genoeg, en er zal misschien ook nog wel een betere oplossing zijn dan die ik voorstel uiteraard. Dit is het eerste wat in me op kwam tijdens het lezen van het topic.
Gewijzigd op 13/06/2013 17:40:11 door Chris PHP
Chris NVT op 13/06/2013 16:59:59:
@Ozzie,
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Of gewoon een datum-veld waarin je de laatste wijziging bijhoudt.
Tijdens het ophalen van de data (zodat je kan gaan bewerken) haal je die op.
Bij updaten update je alleen als de laaste-wijzigings-datum gelijk is aan de datum die je eerst ophaalde. Is dat niet het geval, dan is de datum/tijd dus hoger... en is het record ondertussen geupdate. En dat meld je, maar pas je niets aan!
Dat is logischer en voor meer doeleinden te gebruiken dan een 'locked'-veld.
Eddy, dat gaat toch niet werken? Dan kunnen 2 mensen nog steeds tegelijkertijd in hetzelfde record werken.
Wat ik zelf bij mn website heb is dat er 3 admins zijn. Als er een nieuw lid wordt aangemeld moet deze eerst gevalideerd worden door een admin. De admin die de persoon valideert is tevens ook gelijk de admin van die persoon. Misschien een tip voor je? :)
START TRANSACTION.
Lock record 1
Lock record 2
.
.
.
COMMIT TRANSACTION
Valt de stroom uit of zet je je PC plotseling uit, terwijl er een TRANSACTION nog niet geCOMMIT is, dan wordt er een ROLLBACK gedaan...door de DB zelf.
ROLLBACK = Dat alle reeds gemaakte wijzigingen in de TRANSACTION weer worden teruggedraaid.
Is er zo iets niet in MYSQL ??????
Of moet ik dat inderdaad zoals hierboven wordt voorgesteld zelf allemaal gaan bijhouden.
--> Een aparte tabel maken om de Locks te loggen
--> Om de zoveel tijd deze tabel gaan nalopen of er nog Locks open staan terwijl de sessie reeds is beëindigd
(crontab ????). Maar ja, hoe vaak moet ik dat dan doen. Het liefst om de minuut !?
Is er echt niet zoiets in MYSQL al ingebakken ??????
Is MYSQL wel een volledig Database Management Systeem ??
Eddy E op 13/06/2013 17:57:22:
Of gewoon een datum-veld waarin je de laatste wijziging bijhoudt.
Tijdens het ophalen van de data (zodat je kan gaan bewerken) haal je die op.
Bij updaten update je alleen als de laaste-wijzigings-datum gelijk is aan de datum die je eerst ophaalde. Is dat niet het geval, dan is de datum/tijd dus hoger... en is het record ondertussen geupdate. En dat meld je, maar pas je niets aan!
Dat is logischer en voor meer doeleinden te gebruiken dan een 'locked'-veld.
Chris NVT op 13/06/2013 16:59:59:
@Ozzie,
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Lijkt me wel, vooral als het een webapp is waar je administratie in vast legt. Je wil immers niet hebben dat 3 medewerkers 1 record tegelijk gaan wijzigen, dan kun je er al vanuit gaan dat je gegevens niet meer zullen kloppen.
Of gewoon een datum-veld waarin je de laatste wijziging bijhoudt.
Tijdens het ophalen van de data (zodat je kan gaan bewerken) haal je die op.
Bij updaten update je alleen als de laaste-wijzigings-datum gelijk is aan de datum die je eerst ophaalde. Is dat niet het geval, dan is de datum/tijd dus hoger... en is het record ondertussen geupdate. En dat meld je, maar pas je niets aan!
Dat is logischer en voor meer doeleinden te gebruiken dan een 'locked'-veld.
Dan kunnen er toch nog steeds 2 mensen te gelijk in
Paco de Wulp op 13/06/2013 18:44:28:
Ik dacht dat dit gesneden koek zou zijn......niet dus.. Een kennis (oude) van mij weet dat je in COBOL een record kan lezen met een Lock erop (zodat je deze kan updaten) en niemand anders, zo ook met een complexe transactie, bestaande uit meerdere Locks.
START TRANSACTION.
Lock record 1
Lock record 2
.
.
.
COMMIT TRANSACTION
Valt de stroom uit of zet je je PC plotseling uit, terwijl er een TRANSACTION nog niet geCOMMIT is, dan wordt er een ROLLBACK gedaan...door de DB zelf.
ROLLBACK = Dat alle reeds gemaakte wijzigingen in de TRANSACTION weer worden teruggedraaid.
Is er zo iets niet in MYSQL ??????
Of moet ik dat inderdaad zoals hierboven wordt voorgesteld zelf allemaal gaan bijhouden.
--> Een aparte tabel maken om de Locks te loggen
--> Om de zoveel tijd deze tabel gaan nalopen of er nog Locks open staan terwijl de sessie reeds is beëindigd
(crontab ????). Maar ja, hoe vaak moet ik dat dan doen. Het liefst om de minuut !?
Is er echt niet zoiets in MYSQL al ingebakken ??????
Is MYSQL wel een volledig Database Management Systeem ??
START TRANSACTION.
Lock record 1
Lock record 2
.
.
.
COMMIT TRANSACTION
Valt de stroom uit of zet je je PC plotseling uit, terwijl er een TRANSACTION nog niet geCOMMIT is, dan wordt er een ROLLBACK gedaan...door de DB zelf.
ROLLBACK = Dat alle reeds gemaakte wijzigingen in de TRANSACTION weer worden teruggedraaid.
Is er zo iets niet in MYSQL ??????
Of moet ik dat inderdaad zoals hierboven wordt voorgesteld zelf allemaal gaan bijhouden.
--> Een aparte tabel maken om de Locks te loggen
--> Om de zoveel tijd deze tabel gaan nalopen of er nog Locks open staan terwijl de sessie reeds is beëindigd
(crontab ????). Maar ja, hoe vaak moet ik dat dan doen. Het liefst om de minuut !?
Is er echt niet zoiets in MYSQL al ingebakken ??????
Is MYSQL wel een volledig Database Management Systeem ??
Het heeft alleen dit als dat is wat je bedoelt.
Thx bro.
P.S. Dit lijkt mij toch wel essentieel voor de programmeurs onder ons, om dit te weten.
INTERNET = MULTIUSER...in principe
Gewijzigd op 13/06/2013 19:33:58 door Paco de Wulp
Ik betwijfel of dat doet wat je wil, ik lees nergens dat hij een record locked.
Chris NVT op 13/06/2013 17:38:51:
Het doel ervan is dat mensen niet tegelijk 1 record wijzigen. En dan gaat het hier niet om een adresje wijzigen of iets in die richting maar bijvoorbeeld een stuk tekst aanpassen.
Maar dat kan helemaal niet.... Je kan niet tegelijkertijd iets wijzigen, je kan alleen iets na elkaar wijzigen. MySQL kan namelijk helemaal niet hetzelfde record op hetzelfde moment wijzigen vanaf twee verschillende connecties.
Ho zeg je dan, je bedoelt dat twee mensen tegelijk in hun browser bezig zijn om een wijziging aan te brengen en die dan allebij op zeker moment naar de server sturen om verwerkt te worden. Maar wat is daar het probleem mee? Als ze allebij een wijziging hebben dan worden die na elkaar uitgevoerd. Het enige probleem zou kunnen zijn dat nummer 2 een deel van de wijzigingen van nummer 1 teniet doet. Maar dat kan uberhaupt wel. Ook als je nummer 2 niet de gegevens laat zien zolang nummer 1 niet klaar is. Ook dan kan nummer 2 de wijzigingen van nummer 1 gewoon weer terugdraaien. Dus wat is nu het probleem.
Als je wilt dat nummer 2 zich hiervan bewust is, dan is het veel beter om de oplossing van Eddy te gebruiken. Dus geef een melding dat er in de tussentijd wijzigingen zijn opgetreden. Dan laat je nummer 2 dus gewoon zijn werk doen en je laat hem zelfs gewoon de update uitvoeren als hij dat wil, je maakt hem er alleen op attent dat er iets in de tussentijd is gebeurd.
Veel mooiere oplossing dan zo'n lock mechanisme wat erg onhandig is in een stateless omgeving.