ugrás a tartalomhoz

Adatmódosítás PHP-ből?

H.Z. v2 · 2011. Jún. 22. (Sze), 08.43
Adott egy módosítandó elem az adatbázisban. Betöltöm a módosítható adatokat és kirakom a user elé. User átír benne amit akar és megnyomja az OK gombot.
Program előkeresi a megfelelő sor(oka)t és módosítja őket. Ö... igen... és mi van, ha közben egy másik user ugyanezeket az adatokat már módosította?
Ha nem webről lenne szó, akkor az adatok betöltésekor lockolnám őket (húsz éve, négyfelhasználós rendszeren működött :-) ), de itt csak addig tart a kapcsolat a klienssel, amíg letöltődik az oldal (nem használok perzisztens adatbázis kapcsolatokat), így ha lockolnám is, a lap letöltésének végén a lock megszűnik.

Ilyenkor mi lenne a kulturált megoldás?
Első menetben azt találtam ki, hogy egy timestamp mezőt használok on update current_time-mal. Mielőtt módosítanám, lock, kiolvasom ezt a mezőt, ellenőrzöm, hogy a memóriában lévő értéke egyezik-e a frissen kiolvasottal, ha nem, hiba, ha igen, update, commit, unlock.
Másodikra, hogy timestamp, de triggerből update-elve, mert két timestamp mezőre nem tehetek default/on update-t. De ez sem jó, mert a timestamp csak másodperces bontással tárolódik legnagyobb bánatomra. Marad, hogy mondjuk egy tinyint mező, triggerből automatikusan növelve, túlcsordulás esetén nullázva. Kérdés, hogy ez mennyire számít kulturált megoldásnak? (megfordult a fejemben, hogy checksumot gyártani, de az túlságosan megnövelné a tárolt adatok mennyiségét)

ui: bevallom, most nem vittem túlzásba a keresgélést, este folytatom a kutatást... A PHP/Mysql könyvemben (Hogyan építsünk webáruházat?) nem találtam konkrét megoldást erre - persze lehet, hogy felületes voltam.
 
1

Szerintem az elsõ eldöntendõ,

kuka · 2011. Jún. 22. (Sze), 09.26
Szerintem az elsõ eldöntendõ, hogy mennyire biztonságos megoldást akarsz.

Egy web alkalmazás amelyen dolgoztam és egészen nagy cégek használták, csak annyit tett, hogy amikor valakinek ûrlapban szerkesztésre kiküldte az adatokat, akkor feljegyezete a felhasználó nevét, amikor megkapta a szerkesztett adatokat vagy visszavonták a mûveletet, akkor törölte a nevet. Ha idõközben valaki szerkesztést kért, akkor felugrott egy kérdés, hogy "X felhasználó tudtommal éppen szerkeszti, folytatod?" Elõször furcsáltam ezt a felületes megoldást, de jobban végiggondolva nem valószínû, hogy a bonyolítástól jobbá vált volna.

A színes-szagos megoldás azzal járna, hogy AJAX jelezgessen vissza, hogy még folyik a szerkesztés, a PHP meg minden jelzésre frissítse az adatbázisban azt a timestamp mezõt. Mondjuk AJAX percenként jelezne, a timestamp mezõ másfél perc nem frissítése után tekinteném elhagyottnak és hagynám szerkessze más. Nem látom szükségét másodpercnél pontosabb idõbélyegnek.
2

Maximalista vagyok. Kérdés,

H.Z. v2 · 2011. Jún. 22. (Sze), 09.37
Maximalista vagyok. Kérdés, hogy mennyire akarok biztonságos módszert? ;-)
A színes-szagos rész már részletkérdés. Az elv érdekel. Végül is ez sem rossz amit írsz. Köszi!
3

Marad, hogy mondjuk egy

phtamas · 2011. Jún. 22. (Sze), 17.37
Marad, hogy mondjuk egy tinyint mező, triggerből automatikusan növelve, túlcsordulás esetén nullázva. Kérdés, hogy ez mennyire számít kulturált megoldásnak?

Hogy mennyire kulturált azt nem vagyok hivatott eldönteni, de ez az általánosan használt megoldás. A jobb ORM-ek beépített optimistic offline lock funkciója is pontosan ugyanígy működik, csak ott nem trigger növeli az értéket, hanem php kód.
Ha viszonylag alacsony a conflict valószínűsége egy-egy requestnél, akkor ez a megoldás teljesen használható.
5

Köszi, azért ez vigasztaló...

H.Z. v2 · 2011. Jún. 22. (Sze), 17.54
Köszi, azért ez vigasztaló... :-)
Sajnos még nem volt erőm elmélyedni a témában, egy kevés időt megspóroltál vele.
A trigger ötlete csak azért jött, mert semmi biztosítékot nem látok rá, hogy kizárólag az én PHP programom fog matatni az adatbázison. (pl. mi van, ha valamiért SQL-ből kezdek módosítgatni?)
4

A mi rendszerünkben van egy

Hidvégi Gábor · 2011. Jún. 22. (Sze), 17.51
A mi rendszerünkben van egy központi tábla, ahol nyilvántartjuk, hogy melyik felhasználó melyik rekordot lockolja (nem mysql-ben, ezt a mi végezzük el). Az űrlap bezárásakor a lock felszabadul.
6

Hm. No igen, ez a "végső

H.Z. v2 · 2011. Jún. 22. (Sze), 18.15
Hm. No igen, ez a "végső megoldás", ha jól sejtem.
Azért ezt most nem szeretném implementálni. ;-)
De a kis maximalista lelkemnek eddig ez tetszik a legjobban.
----
Költői kérdés: mi van a beragadó sessionökkel? Gondolom, van a lockon valami épeszű limit és x időn túl érvénytelenné válik. De... mi van, ha a kedves felhasználó meggondolja magát és a lock lejárata után küldi be a módosítását? Gyanítom: mielőtt elfogadná a rendszer a módosítást, ellenőrzi, hogy érvényes-e még a lockja... Hmmmm...
Ha elkészülök azzal, amit most barkácsolok (egy blog, minimális admin felülettel, user regisztrációval), akkor lehet, hogy megpróbálok egy ilyet összerakni én is.
Merő kíváncsiságból. Megfejelve némi Ajax-féleséggel, ami ki is dobja a kedves felhasználót, ha már lejárt a zárolás.
Bár ehhez még Ajax sem kell, elég néhány setTimeout...

ui: jut eszembe, mégsem tetszik annyira, mert nem véd a programot megkerülő, aljas DBA-k tevékenységétől. ;-)
ui2: cserébe nem kell fenntartani egy egyébként felesleges mezőt, minden védendő sorban.
7

Egy órás limit van a lockon,

Hidvégi Gábor · 2011. Jún. 22. (Sze), 18.18
Egy órás limit van a lockon, ha az eredeti felhasználó ez után küldi be, és más már közben lockolta, akkor megjárta.

Sajnos a phpMyAdminos kalózkodástól valóban nem véd : ) De ha tudsz C-ben programozni, a MySQL kiegészítésével ezt megoldhatod : )
8

C?

H.Z. v2 · 2011. Jún. 22. (Sze), 18.22
Kb. elakadtam a helloworld.c önálló megírásánál. ;-)