MySQL SELECT in UPDATE v istem SQL stavku
 
kljuka 12. sep 2011 18:04:36 Pridružen od:
26. feb 2008
4 objav
1 0 0
#1

Ali kdo pozna način, kako iz MySQL baze podatkov najprej izbrati vrstico in jo v istem hipu update-ati. Nekaj takega kot spodaj, a le v enem stavku:




SELECT * FROM ... LIMIT 1;

UPDATE ... SET updating='1' (izbrano vrstici)




Ozadje:

verjetno je to ena najpogostejših operacij: izbereš vrstico, ki jo boš posodabljal in jo označiš kot "zasedeno" - ki se update-a. Naslednji, ki izbira vrstico za posodobljati ne sme izbrati iste, ker se ta že posodablja.

Težava:

Če 2 uporabnika(programa) istočasno izbirata vrstico, ki jo bosta posodabljala, bosta oba izbrala isto (ker je noben še ne uspe UPDATE-ati kot zasedeno).



Kako rešiti zgornji problem v MyISAM bazi podatkov?

Hvala za vse nasvete


všeč(0) ni všeč(0) spam(0)
 
Gogy 12. sep 2011 18:19:23 Pridružen od:
17. mar 2007
2491 objav
2064 252 12
#2

ponavadi delaš tako


UPDATE imetabele tab1
SET imepolja=(SELECT imepolja FROM imetabele2 tab2 WHERE tab1.imepolja=tab2.imepolja LIMIT 1)
WHERE ID=xyz

Se pravi, narediš stavek UPDATE, kličeš pa določen SELECT za neko polje.



Ti to reši problem prve težave?


všeč(0) ni všeč(0) spam(0)
 
Tody 12. sep 2011 18:45:36 Pridružen od:
3. maj 2010
1446 objav
1411 299 25
#3

Zakaj bi dva hkrati updatala isto tabelo (v tisočinko hkrati?) takoj ko nekdo da update na tabelo in vrstico se ta ohrani v seji. Drugemu pa pa reče da ni možno updatat zaradi tega ali onega razloga.



Pozna se šele potem ko prvi da commit. Je pa res da je to iz Oracla vrjetno je tudi tukaj dosti podobno. Tam bi to rešil z pl/sql vrjetno se da tukaj rešit to s kakim php-jem?


všeč(0) ni všeč(0) spam(0)
![](http://www.internetmojster.com/splosno/dobrodelna-akcija.html)
 
Packac 12. sep 2011 18:46:36 Pridružen od:
7. sep 2011
3 objav
0 0 0
#4

Če imaš v tej tabeli nek indikator uporabnika (ali seje, ...), lahko narediš npr. UPDATE pred INSERT:

UPDATE SET updating=1,updater=@1234 WHERE updater=NULL,...

SELECT WHERE updating=1 AND updater@1234, ...



Drugače pa uporabi zaklepanje pred pisanjem na celotni tabeli (LOCK TABLES). MyISAM, če se ne motim, ne podpira zaklepanja na nivoju vrstice.



[EDIT]: Tist updating me moti, zaradi "ing". Če izvajaš več poizvedb, ki so odvisne med seboj nujno s transakcijo.


všeč(0) ni všeč(0) spam(0)
 
kljuka 12. sep 2011 20:16:47 Pridružen od:
26. feb 2008
4 objav
1 0 0
#5

UPDATE imetabele tab1

SET imepolja=(SELECT imepolja FROM imetabele2 tab2 WHERE tab1.imepolja=tab2.imepolja LIMIT 1)

WHERE ID=xyz




Gogy: kako s tem pridobim tudi vsebino vrstice, ki jo bom update-al? Bistvo je, da označim vrstico, ki jo bom posodobil, nato pa to vrstico preberem (da jo lahko začnem obedlovati)




Zakaj bi dva hkrati updatala isto tabelo




Tody: gre za design: ne sme obstajati opcija, da 2 izbereta isto vrstico in jo sočasno posodabljata.




Če imaš v tej tabeli nek indikator uporabnika (ali seje, ...), lahko narediš npr. UPDATE pred INSERT:

UPDATE SET updating=1,updater=@1234 WHERE updater=NULL,...

SELECT WHERE updating=1 AND updater@1234, ...




Packac: tvoja rešitev reši problem, a precej zakomplicira zadevo, ker je potrebno identificirati updater-je in dodati novo polje v tabelo.



Ideja s transakcijami mi je najbolj všeč. Ali MySQL z MyISAM omogoča transakcije? Pa ne sme se zgoditi, da je v času transakcije tabela zaklenjena, ker potem vsi procesi čakajo, kar vodi v ... vedno daljše vrste in kolaps sistema.


všeč(0) ni všeč(0) spam(0)
 
Tody 12. sep 2011 22:00:27 Pridružen od:
3. maj 2010
1446 objav
1411 299 25
#6

naroben topic :)


všeč(0) ni všeč(0) spam(0)
![](http://www.internetmojster.com/splosno/dobrodelna-akcija.html)
 
Packac 12. sep 2011 22:24:52 Pridružen od:
7. sep 2011
3 objav
0 0 0
#7

Smo zakompliciral. Dejansko je OK tako kot imaš nastavljen updating stolpec in s tem lahko implementiraš "row lock".



UPDATE ... SET updating='1 WHERE updating<>1

Potem pa pogledaš affected rows.



Ja, MyISAM ne podpira transkakcij.


všeč(0) ni všeč(0) spam(0)
 
krho 13. sep 2011 06:05:30 Pridružen od:
7. jul 2011
58 objav
26 4 1
#8

od 5.0 naprej imaš SELECT x FOR UPDATE... če se ne motim pa zadeva deluje samo na innodb, ker myisam ne podpira row lockinga


všeč(0) ni všeč(0) spam(0)
www.pagein.si | www.nadzornaplošča.si - Kvalitetno, zanesljivo in cenovno ugodno gostovanje elektronskih poštnih predalov.
 
 

🔒 Za odgovor na to temo se moraš prijaviti.

Prijavi se