Record lock
Pagina: « vorige 1 2 3 volgende »
Erwin H op 13/06/2013 20:44:48:
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.
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.
Ik had eerlijk gezegd wel verwacht dat je zo begrijpen wat ik bedoel, maar ik zal het op een andere manier uitleggen.
Jan en piet werken bij bedrijf X, Jan werkt op PC01 en Piet op PC02. Nu gaat Jan in de webtool een SLA afspraak (Service Level Agreement) wijzigen want er veranderd wat in de uitleg.
Nu denkt Piet, ik zal eens eventjes kijken of alles goed staat, en logt ook in via de webtool. Hey zegt Piet, de uitleg van de SLA afspraak is niet goed, ik zal die eens wijzigen.
Nu is dus zowel Jan als Piet tegelijk iets in 1 record aan het wijzigen, terwijl beide op een andere werkplek zitten. Je gaat dus de teksten van elkaar lopen overschrijven, en zo worden er fouten gemaakt of wijzigingen/aanpassingen gedaan die niet juist zijn.
Wat betreft de transactions. Dit gaat idd niet over het locken van records.
Maar ik ben wel blij dat er überhaupt transactions bestaan in MYSQL :-)
Maar jij bent Developer. Ben jij nooit dit probleem tegen gekomen ??
Ik vind wel : SELECT <TABLE> FOR UPDATE WHERE....
misschien is dit iets...
Ik ga het nog nader uitzoeken, want het moet kunnen........misschien via een omweggetje.. maar zoiets moet kunnen.
Gewijzigd op 13/06/2013 21:39:17 door Paco de Wulp
Chris NVT op 13/06/2013 20:53:06:
Ik had eerlijk gezegd wel verwacht dat je zo begrijpen wat ik bedoel, maar ik zal het op een andere manier uitleggen.
Ik begrijp prima wat je bedoelt, ik zie alleen het praktische nut van die lock niet. Die lock gaat je meer problemen opleveren dan dat het goed doet. Als je de andere oplossing neemt, waarbij je een extra waarschuwing geeft als iemand anders tussen lezen en updaten een update heeft gemaakt, bereik je in mijn ogen genoeg. Uiteindelijk kan elke wijziging alsnog ongedaan gemaakt worden door de volgende update, ook met een lock.
Paco de Wulp op 13/06/2013 19:32:36:
COBOL kent geen transactions/locking/commit etc dus degene die je dat verteld heeft heeft de klok horen luiden maar weet niet waar de klepel hangt. Transactions is wel mogelijk in MySQL maar voor zover ik weet niet in combinatie met PHP en stateles protocol. Gedurende het aanmaken en verzenden van een HTML pagina wordt het php deel "beeindigd" en daarmee ook de MySQL connectie inclusief een gestarte transactie, het transactiemechanisme zal dan impliciet een auto-commit of auto-rollback doen. Vervolgens moet je opnieuw inloggen bij volgende php/mysql bewerking. You are the man. Koen is my Hero !
Thx bro.
P.S. Dit lijkt mij toch wel essentieel voor de programmeurs onder ons, om dit te weten.
INTERNET = MULTIUSER...in principe
Thx bro.
P.S. Dit lijkt mij toch wel essentieel voor de programmeurs onder ons, om dit te weten.
INTERNET = MULTIUSER...in principe
De beste optie is de methode van Eddy met het datum/tijd stempel.
Gewijzigd op 13/06/2013 22:00:58 door Aad B
http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
((( lock record )))
START TRANSACTION; (2de transactie...2de gebruiker)
DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
((((geeft een foutmelding, omdat de SELECT (van de 1ste gebruiker) het record heeft gelocked !))))
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
((( lock record )))
START TRANSACTION; (2de transactie...2de gebruiker)
DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
((((geeft een foutmelding, omdat de SELECT (van de 1ste gebruiker) het record heeft gelocked !))))
Gewijzigd op 13/06/2013 22:03:10 door Paco de Wulp
Paco de Wulp op 13/06/2013 22:02:05:
Klopt, helemaal correct alleen dit kan je niet met HTML/PHP bereiken omdat je werkt met een stateless protocol. Na het opbouwen van de html pagina die je o.a. met php opbouwt is php op een bepaald moment "klaar" en wordt de pagina naar de browser gestuurd en is er voor MySQL dus geen sprake meer van een open transactie. De transactie wordt namelijk beeindigd (uitgelogd uit MySQL) zodra php "klaar is"http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
((( lock record )))
START TRANSACTION; (2de transactie...2de gebruiker)
DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
((((geeft een foutmelding, omdat de SELECT (van de 1ste gebruiker) het record heeft gelocked !))))
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
((( lock record )))
START TRANSACTION; (2de transactie...2de gebruiker)
DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
((((geeft een foutmelding, omdat de SELECT (van de 1ste gebruiker) het record heeft gelocked !))))
Toevoeging op 13/06/2013 22:11:28:
@ Aad B
Klopt, helemaal correct alleen dit kan je niet met HTML/PHP bereiken omdat je werkt met een stateless protocol. Na het opbouwen van de html pagina die je o.a. met php opbouwt is php op een bepaald moment "klaar" en wordt de pagina naar de browser gestuurd en is er voor MySQL dus geen sprake meer van een open transactie. De transactie wordt namelijk beeindigd (uitgelogd uit MySQL) zodra php "klaar is"
Hier moet ik even over nadenken...
Thx
Gewijzigd op 13/06/2013 22:12:35 door Paco de Wulp
Gewijzigd op 13/06/2013 22:25:23 door Aad B
Paco de Wulp op 13/06/2013 19:32:36:
P.S. Dit lijkt mij toch wel essentieel voor de programmeurs onder ons, om dit te weten.
Paco de Wulp op 13/06/2013 21:20:47:
@ Chris
...
Maar jij bent Developer. Ben jij nooit dit probleem tegen gekomen ??
...
Maar jij bent Developer. Ben jij nooit dit probleem tegen gekomen ??
Het zal wel aan mij liggen, maar ik vind je uitspraken een beetje raar. Omdat iemand developer is moet ie dus gelijk alle situaties ooit zijn tegengekomen? Zo werkt het dus niet.
Maar goed... ik denk dat je niet zozeer moet denken in termen van via de database een record vergrendelen, maar via je code. Het gaat erom dat niet 2 mensen hetzelfde nieuwsbericht aan het wijzigen zijn. Het is heel vervelend dat als Pietje net 30 regels tekst heeft getypt, en Jantje vervolgen die tekst overschrijft met zijn 20 regels tekst.
Oplossing? Waarschuw de user VOORDAT hij een nieuwsbericht gaat wijzigen, dat iemand anders met dit nieuwsbericht bezig is. En dat is dus de oplossing die Chris eerder noemde.
Thx.
Paco.
Paco de Wulp op 13/06/2013 21:20:47:
@ Chris
Wat betreft de transactions. Dit gaat idd niet over het locken van records.
Maar ik ben wel blij dat er überhaupt transactions bestaan in MYSQL :-)
Maar jij bent Developer. Ben jij nooit dit probleem tegen gekomen ??
Wat betreft de transactions. Dit gaat idd niet over het locken van records.
Maar ik ben wel blij dat er überhaupt transactions bestaan in MYSQL :-)
Maar jij bent Developer. Ben jij nooit dit probleem tegen gekomen ??
Je kunt transactions niet gebruiken in combi met PHP, het is handig voor applicaties zodat je niet definitief schrijft.
Ja ik ben developer, echter werkt ik niet als developer voor een groot bedrijf. De klanten die ik heb vanuit mijn eigen bedrijf zijn kleinere bedrijven. De webapps die ik voor hun gemaakt heb hebben geen problemen met meerdere gebruikers en dat ze elkaars records gaan wijzigen.
Vandaar ook deze oplossing, zoals ik al zei die is niet fail-proof, maar het is een relatief makkelijke oplossing voor je probleem.
En met de verschillende oplossingen die ik gegeven heb rond het lock probleem moet het wel te doen zijn. Je hoeft het uiteraard niet te gebruiken, het was puur om je te helpen.
Je kunt documenten laten uitchecken en weer inchecken via de database. Dat is bij systemen met meerdere auteurs niet ongebruikelijk (bijvoorbeeld SharePoint). Als een journalist enkele alinea's aan het herschrijven is, wil je bijvoorbeeld niet dat een eindredacteur dezelfde alinea's onder handen neemt. Je laat de eerste gebruiker het document dus uitchecken, waarbij het voor anderen tijdelijk ontoegankelijk is (of alleen-lezen). Is de gebruiker klaar met het doorvoeren van wijzigingen, dan wordt het document weer ingecheckt.
Dit uit en en checken, is dat een functionaliteit die MySQL of PHP standaard bied? Of moet je zoiets zelf schrijven, zoals bijvoorbeeld een lock systeem?
Chris NVT op 14/06/2013 12:57:24:
Dit uit en en checken, is dat een functionaliteit die MySQL of PHP standaard bied? Of moet je zoiets zelf schrijven, zoals bijvoorbeeld een lock systeem?
Die functionaliteit moet je zelf bouwen, om verschillende redenen. De locks in MySQL worden slechts gedurende fracties van seconden gebruikt om conflicten te voorkomen. Dat werkt niet als een medewerker tientallen minuten aan een document gaat sleutelen.
Je kunt het vergelijken met iemand die een dossier uit een archiefkast haalt en ermee naar zijn bureau loopt. Terwijl hij/zij aan het dossier werkt, is het tijdelijk niet beschikbaar voor anderen.
Dacht dat MySQL of PHP dit misschien al zou ondersteunen, maar dat is nog niet het geval dan ;-)
Plan B is elke nieuwe versie apart opslaan. Dat is echter alleen zinvol als je een "rollback" wilt kunnen uitvoeren naar elke vorige versie of als je exact wilt registreren wie-wat-wanneer heeft gewijzigd.
http://webcheatsheet.com/php/record_locking_in_web_applications.php, of je kan ook dit gebruiken (eerste antwoord). Dat is misschien nog wel beter.
Je kan een side-by-side bestand laten zien waarin de veranderingen te zien zijn. Net zoals die te zien zijn bij Git, zie bijvoorbeeld https://github.com/symfony/symfony/commit/25e3abd683727bde9acadb0994487debac644e94.
Er zijn zelfs al voorbeelden van record locking beschikbaar, zoals op Je kan een side-by-side bestand laten zien waarin de veranderingen te zien zijn. Net zoals die te zien zijn bij Git, zie bijvoorbeeld https://github.com/symfony/symfony/commit/25e3abd683727bde9acadb0994487debac644e94.
Een datum (als lock) opslaan in het record zelf. Indien de update klaar is datum weer op null zetten (unlocken). Mocht de stroom of connectie verloren gaan, dan geldt de lock hooguit één dag, zodat de volgende dag de lock automatisch niet meer geldt (naar gelang kan deze locktijd (datum=dag) ook nog op tijd (timestamp) gebeuren, zodat bijvoorbeeld een lock maximaal een halve dag kan gelden of slecht 2 uur, oid.).
(In geval van nood, kan natuurlijk de administrator de lock al eerder ongedaan maken, door de datum op nul te zetten)
Het is en blijft behelpen.....
Gewijzigd op 14/06/2013 13:53:52 door Paco de Wulp
En hoe ga je dan zorgen dat ze na een xx bepaalde tijd weer op null komen te staan? MySQL zal niet 'automatisvch' de tijd op null zetten als je daar geen script/cronjob voor schrijft.
P.S. Ik zou ook de sessie erbij kunnen opslaan, zodat ik kan kijken of deze sessie nog actief is. Is deze sessie niet meer actief vervalt de lock ook.
Dus:
Lock geldt niet als datum < huidige datum
Lock geldt niet als datum = 0
Lock geldt niet als sessie niet meer actief is
Gewijzigd op 14/06/2013 14:12:30 door Paco de Wulp