16. august 2006 - 14:40Der er
15 kommentarer og 1 løsning
forhindre 2 i at læse det samme (semaphore)
Hej
Jeg har en C++ applikation der kører og tjekker i databasen, den ser om der er noget scheduleret i en tabel. Men jeg vil gerne have dette program til at køre på flere maskiner samtidig, som læser op mod den samme database. Jeg har alt forbindelse klar og den kan også sagtens gøre det, men jeg har ikke haft applikationerne til at køre samtidig på 2 maskiner, for de må IKKE tage den samme "task" fra min scheduled tabel.
Det vil sige at når applikationen har læst at der er noget der skal laves, ændrer den state fra 0 til Started. Og derefter vil ingen af de andre maskiner tage samme task, medmindre state bliver sat til 0 igen (state kan også være lig "Force", men det betyder ikke så meget i denne sammenhæng). Det jeg så vil høre om der er nogen der har lavet eller ved hvordan man laver således at der bliver lavet en slags semaphore-styring, således at 2 maskiner ikke kan læse i databasen samtidig eller helst ikke i den samme tabel samtidig? således at 2 maskiner ikke kan begynde den samme task.
Jeg vil helst ikke at de skal kommunikere internt, da der kan være fra 1-xx maskiner der skal kunne læse her, derfor ville det være godt hvis tabellen "låste" når der var en applikation der prøvede at få fat i den...
Jeg er lidt ny i MySQL, så bær lige over med mig... Især hvis funktion er lige til og allerede lavet.
Manuelle og semi-automatiske strategier for identitetsstyring virker - lige indtil nogen beder om dokumentation. For at undgå denne fare har DKTV taget kontrol over sin identitets- og adgangsstrategi.
Tak for svaret... men nu er det sådan at jeg på den maskine jeg udvikler det på bruger InnoDB, men jeg er ret sikker på at der vil ligge MyISAM på maskinen når den bliver lagt på nettet... (det er en linux-maskine)
jeg går igang med at læse din artikel ... jeg kan se du skriver om tingene... men jeg ved ikke lige hvilken løsning der egner sig, da jeg gerne vil lave en generel løsning, hvis det senere skal flyttes.
jeg ved godt det er en C++ applikation, og at den ikke ligger på nettet, men det gør databasen, som får data udefra, og deri læser C++ appliktaionen...
Jeg har nu lavet det med LOCK TABLES ... og dette betyder ikke så meget, for det er kun 1 sted i alle applikationer hvor det er nødvendigt, fordi at de ikke skal starte samme task. Derefter er en af felterne sat fra 0 til started, og den kan dermed ikke "tages" mere.
Tak for hjælpen. Jeg har dog ikke testet det på MyISAM systemet, men det virker fint på min egen InnoDB
mysql_query("LOCK TABLES table_name WRITE;"); mysql_query("SELECT * FROM table_name WHERE field_name = '0'"); mysql_query("UPDATE table_name SET field_name = 'started' WHERE Id = id_from_select_query"); mysql_query("UNLOCK TABLES;");
Det skal lige siges at det er meget vigtigt at huske ; i LOCK TABLES queries, ellers virker det ikke :)
Ja jeg ved det godt, for jeg kunne godt se meningen med det andet. Dog er det så kort tid at den låser tabellen at det ikke vil have noget at sige. Det eneste den gør er at låse tabellen, derefter lavet et select-kald og så opdatere 1 felt og så låse op igen.
Kaldet er ens hver eneste gang, med de samme krav, så det vil ikke gå galt.
Mange tak for hjælpen.
Synes godt om
Slettet bruger
20. august 2006 - 22:59#9
En anden mulighed kunne være at lave en ny tabel med oplysning om hvem, der "har" den pågældende task. Denne tabel skal så have samme primærnøgle som din nuværende tabel.
Når dit program så vil tage en task, skal den først lave en INSERT i stil med:
INSERT INTO taskowner (id, owner) VALUES (taskid, processid)
Hvis denne INSERT giver affected rows=1, så var den taks ikke taget, ellers skal programmet vælge en anden task.
Synes godt om
Slettet bruger
20. august 2006 - 23:00#10
Til den simple brug, jeg har nævnt her, er det forresten ikke engang nødvendigt med owner-kolonnen i den ny tabel.
Jeg tror måske at det er mere sikkert at bruge LOCK TABLES, for der kan de ikke komme til at læse og skrive samtidig, og derfor kan de ikke fx lave samme insert kommando samtidig...
eller ? ... Jeg har valgt at bruge LOCK TABLES.
Synes godt om
Slettet bruger
21. august 2006 - 11:15#12
Ja det virker også at låse en tabel, det var mere for at gøre opmærksom på den anden mulighed.
Og det kan ikke lade sig gøre, at to kommer til at lave samme INSERT, da de så vil have samme primærnøgle, og det forhindrer MySQL (Den giver en DUPLICATE KEY fejl for den, der kommer som nummer to).
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.