Jump to content
php.lv forumi

Transakcijas un kursori PgSQL


ivka

Recommended Posts

Atkal jau lietus līst un atkal kaut kas manuāļos nav līdz galam uzrakstīts...

Tātad - vai kādam ir sanācis ņemties ar PostgreSQL un transakcijām, izmantojot PHP par frontendu? Problemātika sekojoša:

 

1) PHP patīk rejūzot jau esošas atvērtas konekcijas ar datubāzi. Respektīvi, ja man viens apache childs apstrādā 7 klientus, tad visticamāk ka šamiem visiem tiks izmantota viena un tā pati konekcija ar datubāzi.

2) Transakcijas, kā zināms, darbojas pa visu db konekciju, respektīvi - ja viens useris izpilda BEGIN, tad otrs, kurš pa to laiku izpilda kaut ko citu, visticamāk trāpa iekšā iesāktajā transacijas blokā, un ja pirmajam pēkšņi notiek ROLLBACK, tad otrajam arī nekas nesanāk, jo šie sanāk ka ir lietojuši vienu transackciju.

 

Tas viss principā ir nepieciešams, jo ir vēlme izmantot kursorus (DECLARE my CURSOR FOR SELECT.......) un sekojoši ar FETCH bīdīties pa recordiem pēc vajadzības. Gribas, lai skripta sākumā notiktos BEGIN, bet beigās COMMIT vai kaut kur pa vidu ROLLBACK. Visideālāk, protams, būtu, ja db konekciju varētu piesiet pie usera sesijas un managēt šīs konekcijas, tad varētu reāli sabūstot performanci ar šitām lietām, jo pie katra page refresha taisīt 20 selektus nav ne vēlmes ne arī principiālas nepieciešamības.

 

Komentāri? Zinu ka pg_connect() var izsaukt ar PGSQL_CONNECT_FORCE_NEW :-)

 

Vairāk interesē principiālā pieeja - vai kāds kaut ko tādu ir darījis un cik liels čakars bija?

Vai arī vispār es te murgoju un nekad nevar sanākt tā ka viens useris trāpa otra iesāktajā transakcijā....

Link to comment
Share on other sites

:huh: vai tad var viens useris dziivoties pa cita usera transakciju?

19729[/snapback]

 

Par to jau jautājums :-) Ja zinātu ka var droši pages sākumā izpildīt BEGIN un beigās COMMIT, būtu baigi labi.. Bet kaut kā nav pārliecības.

Link to comment
Share on other sites

Labi. Laikam pats visu sapratu - biju noputrojies ar persistentajām konekcijām un principā uztraukumam nav pamata. Varbūt kādam noderēs mazliet teorijas..

 

Katrs apache childs vienlaicīgi servē vienu rekvestu. Tas gan nenozīmē, ka vienam userim taisot vairākus rekvestus viņš visu laiku strādās ar vienu un to pašu childu!!! Citiem vārdiem - mans.php fails no sākuma līdz beigām, ieskaitot visas includes utt. atrodas viena apaches childa ietvaros un citi useri pa to laiku pie šī childa resursiem (piemēram db konekcijām) netiek. Tas, savukārt, nozīmē, ka jebkādas transakcijas, kas sāktas konkrētā skriptā, ir ekskluzīvi pieejamas šim skriptam. Ja nelieto persistentās konekcijas, tad konekcija ar datubāzi tiek aizvērta skriptam izbeidzoties. Neesmu 100% pārliecināts, bet šķiet, ka ja netaisa COMMIT, tad viņš automātiski nenotiek.

 

Fckn slikti vārdu sakot - db konekcijas dzīvo tikai skripta izpildes laiku un ne vairāk. Persistentās nepalīdz. Nošauties... Labi ka neprogrammēju PHP ikdienā...

Link to comment
Share on other sites

Te jau par ko bazars.. Ja nelieto begin commit, tad uz selektu rezultātiem fig var paļauties, jo cits useris pa vidam var visu nodzēst vai izUPDATēt, bet ja lieto, tad par to nav jāuztraucas.

Link to comment
Share on other sites

Varbūt kādam noderēs mazliet teorijas..

 

Katrs apache childs vienlaicīgi servē vienu rekvestu. Tas gan nenozīmē, ka vienam userim taisot vairākus rekvestus viņš visu laiku strādās ar vienu un to pašu childu!!!

Neliela piebilde: šis ir patiesi tikai par prefork moduli.

Citi Apaches MPM moduļu childi lielākoties threadojas un ar vienu childu tiek apstrādātas vairākas ienākošās konekcijas/requesti.

 

Ja rekvesti tiek izdarīti KeepAliveTimeout robežās tad vienai un tai pašai konekciju requestus apstrādā tas pats childs līdz brīdim kad akal tiek pārsniegts MaxRequestsPerChild iestādijums - tad apaches childs tiek nokillots un piestartēts jauns vai izmantos kāds rezerves (spare child).

Link to comment
Share on other sites

×
×
  • Create New...