Novo

Forum kao aplikacija na telefonu

Dodajte forum na početni ekran i koristite ga kao aplikaciju, sa menijem na dnu ekrana.

  • 7 odgovora
  • 3.110 pregleda

Najnovija ↓

Formulari i 'race condition' 20.05.2012. u 13:54 · pre 175 meseci #1
Šta se u praksi pokazalo kao najbolje rešenje za sprečavanje 'race condition' situacije kod editovanja formulara ?

Primer:

Administrator 1 je otvorio formu stranicu kojom posmatra sadržaj nekog zapisa iz baze, i počinje da ga edituje, jer mu se recimo ne sviđa naslov artikla.

Administrator 2 zatim otvara na svom računaru istu tu stranicu i gleda sadržaj istog tog zapisa iz baze, jer recimo želi da cenzuriše psovku iz teksta artikla.

Admin 1 je izmenio naslov i pritiska dugme 'Save' i snima nov sadržaj formulara u bazu.

Admin 2 završava cenzurisanje teksta i pritiska 'Save'. Time u stvari on pregazi naslov teme originalnim sadržajem i tako slučajno anulira efekat prvog admina.

Kako je to rešeno u nekim većim sistemima ?
Zaključavanje editovanja zapisa ne dolazi u obzir.
Potpis
"The quieter you become, the more you are able to hear."
Blog | PowerCMS
Re: Formulari i 'race condition' 20.05.2012. u 14:14 · pre 175 meseci #2
moje mišljenje je da se upiše u bazu da admin 1 edituje to i to i onda na save adminu 2 kaže da je admin 1 menjao ili menja stranicu i pita ga da li sigurno želi da pregazi promene. tako radi wordpress
Re: Formulari i \'race condition\' 16.07.2012. u 19:08 · pre 174 meseca #3
Citat:
Miroslav Ćurčić:
Šta se u praksi pokazalo kao najbolje rešenje za sprečavanje 'race condition' situacije kod editovanja formulara ?
Kako je to rešeno u nekim većim sistemima ?
Zaključavanje editovanja zapisa ne dolazi u obzir.


http://en.wikipedia.org/wiki/Database_transaction
Potpis
Nebojša Đorđević - nesh
http://younify.nl
Re: Formulari i 'race condition' 18.07.2012. u 16:10 · pre 173 meseca #4
Imaš nekoliko varijanti:

1) Prva je ovo što je PHPovac predložio, tipa da napišeš poruku "Korisnik X edituje ovaj formular", pa pustiš čoveka da se dovikuje sa X-om o tome šta da se radi.
2) Ono što ja prefereriram da uradim je sledeće:

Svaka tabela ima "modified" polje (ON UPDATE CURRENT_TIMESTAMP varijanta). Kada čovek otvori stranicu, tj. kada imaš GET poziv (ako je tako rešeno), sačuvaš vreme tog događaja. Kada klika na Save, proveriš "modified" polje. Ako je $modified > $otvaranje_formulara, prikažeš stranicu koja opisuje konflikt. Npr. prikažeš paralelno dva formulara, jedan sa izmenama koje je čovek hteo da izmeni, drugi sa aktuelnim podacima (koji su oni koje je drugi admin u međuvremenu sačuvao).

Onda čoveku daš opcije koje bi ti dao bilo koji versioning system:

- mogućnost da koristi postojeće izmene, tj. da odbaci svoje
- mogućnost da koristi svoje izmene i mogućnost da ih menja, da bi prilagodio onome što vidi kao aktuelne informacije.

Ova varijanta je dobra jer ne moraš da diraš bazu. Sve izmene čuvaš u sesiji (tj. samo ih prebacuješ iz poziva u poziv) i porediš sa stvarima u bazi. Možeš i u nedogled da vrtiš, tj. ako 5 ljudi radi na istom formularu, ti uvek za svakog proveravaš kada je poslednji put otvorio formular i kako se poredi sa "modified" poljem.

3) Konačno, možeš da napraviš ceo versioning sistem. Umesto jednog reda za jedan unos u bazi, imaš N redova, svaki sa timestampom i najnoviji timestamp je aktuelna verzija. Onda korisnici mogu da roll-backuju izmene, da ih uporede itd. Ako očekuješ puno takvih konflikta, onda je to prava stvar, ali i najkomplikovanija.
Re: Formulari i 'race condition' 18.07.2012. u 19:44 · pre 173 meseca #5
@nesh
Kako? Moze li simple primer koda?
Potpis
[Ovu poruku je menjao VladaSu dana 14.06.2003. u 11:22 GMT+1]
Re: Formulari i \'race condition\' 19.07.2012. u 13:05 · pre 173 meseca #6
Citat:
VladaSu:
@nesh
Kako? Moze li simple primer koda?


Prilično sam siguran da se to ne može rešiti transakcijama. One imaju drugu svrhu. Npr:

Hoćeš da updateuješ tabelu A i onda u tabelu B da uneseš, npr. informaciju da si updateovao nešto. Ako uradiš čisto (presudocod):

Code:
1) mysql_query(UPDATE a SET x = 1 WHERE id = N)
2) mysql_query(INSERT INTO b (poruka) VALUE (N je updateovan))


Ovo pod 2) će se izvršiti čak i ako ovo pod 1) nije uspelo. Ako je ovo pod 1) uspelo, onda će postojati trenutak u vremenu kada će tabela A biti ažurirana, ali tabela B neće.
Onda to rešiš sa (opet pseudokod)

Code:
mysql_query(START TRANSACTION)
mysql_query(UPDATE a SET x = 1 WHERE id = N)
mysql_query(INSERT INTO b (poruka) VALUE (N je updateovan))
if (mysql_affected_rows()) { // Vrati 1, tj. TRUE ako je prethodan query nešto uspeo
  mysql_query(COMMIT)
} else {
  mysql_query(ROLLBACK)
}


Kada uradiš COMMIT, OBA querya će biti sačuvani u bazi. Kada uradiš ROLLBACK, kao da se ništa nije desilo...

Dakle, neprimenjivo za zadati problem :)
Re: Formulari i 'race condition' 20.07.2012. u 08:57 · pre 173 meseca #7
@cabrilo
Znam sta su transakcije i znam da ne moze ovaj problem da se resi transakcijam, zato i pitam za primer koda a ne samo povrsno procitana teorija :)
Potpis
[Ovu poruku je menjao VladaSu dana 14.06.2003. u 11:22 GMT+1]
Re: Formulari i 'race condition' 21.07.2012. u 18:27 · pre 173 meseca #8
Imas u tabeli koju editujes polje version koje svaki put kada update-ujes inkrementiras za jedan.

npr. kada popunjavaš formu uradi sledeći upit.

Code:

SELECT username, ime, prezime, version FROM korisnici


Dobiješ neki odgovor od baze
username: pero
ime: petar
prezime: peric
version: 21

Kad završiš editovanje i klikneš na Save uradiš sledeće:
Code:

UPDATE korisnici SET
username = '.......',
ime = '.......',
prezime  = '.......',
verison = verison +1
WHERE username = 'pero' AND version = 21;


Nakon ovoga provjeriš koliko je kolona updateovano, ukoliko je to 0 onda znači da je neko u međuvremenu to ažurirao i da je verzija uvećana, da tvoj WHERE uslov ne pije vode i obavjesti korisnika o tome. A evo kako to možeš da provjeriš:
http://php.net/manual/en/mysqli.affected-rows.php

Inače ova metoda se zove optimistic locking.
Sviđa mi se1
Prijavite se da biste odgovorili u ovoj temi.PrijavaRegistracija

Premeštanje teme