Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Formulari i 'race condition'

[es] :: PHP :: Formulari i 'race condition'

[ Pregleda: 2003 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Miroslav Ćurčić
ex mVeliki
Novi Sad

Član broj: 19034
Poruke: 1118
*.adsl.eunet.rs.



+19 Profil

icon Formulari i 'race condition'20.05.2012. u 12:54 - pre 144 meseci
Š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.
"The quieter you become, the more you are able to hear."
Blog | PowerCMS
 
Odgovor na temu

PHPovac

Član broj: 300013
Poruke: 168
*.dynamic.isp.telekom.rs.



+19 Profil

icon Re: Formulari i 'race condition'20.05.2012. u 13:14 - pre 144 meseci
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
 
Odgovor na temu

nesh
Đorđević Nebojša
Younify - Magento (PHP) development
Niš

Član broj: 668
Poruke: 127
*.exe-net.net.

Sajt: nesh-microblog.blogspot.c..


+2 Profil

icon Re: Formulari i \'race condition\'16.07.2012. u 18:08 - pre 142 meseci
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
Nebojša Đorđević - nesh
http://younify.nl
 
Odgovor na temu

cabrilo
Dejan Cabrilo

Član broj: 4780
Poruke: 56
92.244.141.*

ICQ: 7366253


Profil

icon Re: Formulari i 'race condition'18.07.2012. u 15:10 - pre 142 meseci
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.
 
Odgovor na temu

VladaSu

Član broj: 31634
Poruke: 1099
*.dynamic.isp.telekom.rs.



+218 Profil

icon Re: Formulari i 'race condition'18.07.2012. u 18:44 - pre 142 meseci
@nesh
Kako? Moze li simple primer koda?
[Ovu poruku je menjao VladaSu dana 14.06.2003. u 11:22 GMT+1]
 
Odgovor na temu

cabrilo
Dejan Cabrilo

Član broj: 4780
Poruke: 56
92.244.141.*

ICQ: 7366253


Profil

icon Re: Formulari i \'race condition\'19.07.2012. u 12:05 - pre 142 meseci
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 :)
 
Odgovor na temu

VladaSu

Član broj: 31634
Poruke: 1099
*.dynamic.isp.telekom.rs.



+218 Profil

icon Re: Formulari i 'race condition'20.07.2012. u 07:57 - pre 142 meseci
@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 :)
[Ovu poruku je menjao VladaSu dana 14.06.2003. u 11:22 GMT+1]
 
Odgovor na temu

bantu

Član broj: 38670
Poruke: 305
..ppoe.dyn.broadband.blic.net.



+27 Profil

icon Re: Formulari i 'race condition'21.07.2012. u 17:27 - pre 142 meseci
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.
 
Odgovor na temu

[es] :: PHP :: Formulari i 'race condition'

[ Pregleda: 2003 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.