Jump to content

Oracle locking session


Ronalds
 Share

Recommended Posts

Lūk, ir problēma. Lokojas sessija. Kļūdas paziņojuma nav, softs pamirst kamēr nav nokomitota vai rolbakota sesija.

 

Webā pilns ar komandām, kur var paskatīties kas loķē pasākumu. Users, programmas nosaukums, darbsacija.

 

Bet nekur nevaru atrast kā uzzināt kuras SQL komandas izsauc loķēšanu.  Varbūt kāds zin?

Link to comment
Share on other sites

Maina tos pašus datus un ilgi nesaglabā. Tas arī noved pie lokošanās.

 

 

REM Sesiju saraksts:

select v.status,round((sysdate-v.logon_time)*24,2) ilgums,v.logon_time, v.*
from sys.V_$SESSION v
order by v.status,v.username

REM Aktīvās komandas:

select v.status,round((sysdate-v.logon_time)*24,2) ilgums,v.logon_time, v.username,v.SID,
s.sql_text,s.elapsed_time,s.CPU_TIME,
v.osuser,v.machine,v.terminal,v.program,v.module
from sys.V_$SESSION v,sys.v_$sqlarea s
where v.sql_hash_value = s.hash_value(+)
and v.sql_address    = s.address (+)
and v.username='jūzerneims'
order by v.status,v.username,v.logon_time

REM Killošanas skripts:

select sid,status,username,logon_time,
'alter system kill session '''||to_char(SID)||','||to_char(serial#)||''';'
from sys.V_$SESSION v
where username='jūzerneims' and status<>'KILLED'


REM Loki

select o.* ,
(select owner from dba_objects d where d.object_id=o.object_id) owner,
(select object_name from dba_objects d where d.object_id=o.object_id) object_name,
(select object_type from dba_objects d where d.object_id=o.object_id) object_type
from V$LOCKED_OBJECT o
order by (select object_name from dba_objects d where d.object_id=o.object_id)

http://oracle-info.com/2013/01/31/basics-oracle-enqueue-waits-causes/

Link to comment
Share on other sites

Paldies! Atradu komandu!

 

Bet vai nav kāda iespēja lai update negaida uz loķētiem ierakstiem? 

Bez select for update nowait? Ja nav iespējams izmainīt to aplikāciju kas loķē ierakstus? 

Link to comment
Share on other sites

Var gadīties, ka ar izmaiņu saglabāšanu viss ir kārtībā, bet komandām transakcijā ir neoptimāls izpildes plāns, tādēļ tās pildās ilgi un traucē citiem lietotājiem.

Palīdzēs indeksu pamainīšana, statistiku pavākšana. Varbūt vienkārši kāds indekss ir invalidējies? Pārkompilē.

 

Problēma iestājās pēkšņi vai arī lietotāji ar to sadzīvoja jau gadiem?

Link to comment
Share on other sites

Veidoju jaunu aplikāciju, jeb pareizāk sakot mēģinu saglābt gadiem ilgi veidotu aplikāciju.

Sākotnējā aplikācija ir viens vienīgs murgs, sākot ar tabulu struktūru un programmēšanas stilu, beidzot ar gui izskatu un funkcionalitāti..... 

 

Es lietoju 

DELPHI + http://www.devart.com/odac/

 

Jau kādus gadus 10 taisu līdzīgas aplikācijas pamatā izmantojot firebird kā sql serveri un fibplus kā pieejas komponentus. Bet ir arī ar MySQL un MSSQL strādāts. Principā viss oki.

 

Ar ORACLE - viens vienīgs murgs ;( ;( ;(

Sākumā jau mutanting table problēma - izrādās oracle trigeri stipri ierobežoti... Nu labi. Datu integritātes uzturēšanu daru no GUI aplikācijas (citos sql serveros visu ar trigeriem darīju), man tas nepatīk, bet nav izvēles...

 

Bet te nevar vienu datu gridu vairāki cilvēki vienlaicīgi labot. ti. kaut kādos momentos var, kaut kādos nevar. Skaidrs ka vienu ierakstu nevar vairāki cilvēki vienlaicīgi labot. Bet es palaižu divas aplikācijas instances, vienā izlaboju ierakstu (bet nekomitēju tranzakciju), tad atkarībā no tā vai pirmā aplikācija ir nolokojusi ierakstu ar select for update nowait.

 

Ja ir nolokojusi - tad mēģinot labot to pašu ierakstu - dabūju kļūdas paziņojumu, kas ir loģiski. Mēģinot labot citu ierakstu - aplikācija uzkarās - gaida kamēr tiks pabeigta pirmās aplikācijas tranzakcija. 

 

Ja nav nolokojusi - tad mēģinot labot to pašu ierakstu aplikācija uzkaras - gaida pirmās aplikācijas tranzakcijas beigas. (arī loģiski, bet moš var uzrakstīt updeit statmentu kur negaida uz citām tranzakcijām, bet uzriez atgriež kļūdu?)  Citus ierakstus var labot bez problēmām.... 

 

Īstenībā baigā pakaļa... jau 3 dienas pie ši sēžu, eksperimentēju, googlēju, lasu dokumentāciju...  Klients neapmierināts, nekas nestrādā ...   ;(

Labots - ronalds_
Link to comment
Share on other sites

Paskaties komponentēm propertijus, varbūt var sūtīt uz bāzi apdeitus īsi pirms commita. Otrajos delfos bija "cached updates" fīča.

 

Patreiso, kādas komandas tiek sūtītas uz datubāzi. Ja apdeitam kritērijos nav primārās atslēgas vai rowid, nav brīnums, ja lokojas visa tabula.

 

Trigeru mutācijas var dabūt, kad trigeris netieši sāk ietekmēt tabulu, uz kuras pats sēž. JA datu atkarības ir tik sarežģītas, kontroli var ielikt db procedūrās un pasaukt transakcijas beigās no klienta.


Ja grida apdeiti parauj trigerus, kas samaina pusdatubāzi, tad tas arī var būt skaidrojums. Risinājums: turēt atvērtu transakciju pēc iespējas īsāku laiku vai arī trigeru loģiku pārcelt uz procedūrām.

Link to comment
Share on other sites

Paskaties komponentēm propertijus, varbūt var sūtīt uz bāzi apdeitus īsi pirms commita. Otrajos delfos bija "cached updates" fīča.

 

Ir cached updates. Bet to negribu lietot jo tad pilnībā no trigeriem jāatsakās, nevar pat tādas elementāras lietas kā "summa= daudzums x cena"  trigeros lieto. Bet tīri datu manipulāciju kods iekš trigeriem ir krietni īsāks un vieglāk saprotams, nekā no delphi.

Iekš trigera:

:new.summa := :new.cena * :new.daudzums

 

iekš delphi:

dataset.FieldByName('summa').asCurrency:= dataset.FieldByName('cena').asCurrency * dataset.FieldByName('daudzums').asCurrency

 

Tas tikai piemērs - reāli krietni vairāk aprēķinus vajag..... 

 

 

 

 

Trigeru mutācijas var dabūt, kad trigeris netieši sāk ietekmēt tabulu, uz kuras pats sēž

 

Ne tikai. Super piemērs. Rēķina preču sarakstam vajag iespēju lai klients var pats sakārtot preces sev vēlamā secībā. Ieviešam lauku NPK, pēc kura kārtojam rindas pirms drukāšanas.

 

Bet to lauku vajag aizpildīt. Iekš firebirda trigerī before insert tabulai rekini_preces rakstām: 

if :new.npk is null then select max(npk)+10 from rekini_preces where rekins_id= :new.rekins_id into :new.npk

Viss notiek! Oracle = mutating table error....  Redziet trigeris nevar lasīt no tabulas, no kuras viņš ir izsaukts. Bet ja delphi komponentā uz eventa beforePost izpildu šo pašu pieprasījumu, tajā pašā tranzakcijā - viss strādā! 

 

 

 

Ja grida apdeiti parauj trigerus, kas samaina pusdatubāzi, tad tas arī var būt skaidrojums.

Eksperimentam tika atslēgti visi trigeri. Skuju, tāpat... Mistika... Vai nu oracle vai tā ODAC gļuki.....   ;(

Labots - ronalds_
Link to comment
Share on other sites

Bet to lauku vajag aizpildīt. Iekš firebirda trigerī before insert tabulai rekini_preces rakstām: if :new.npk is null then select max(npk)+10 from rekini_preces where rekins_id= :new.rekins_id into :new.npk

Prieksh taa Oraaklii ir taada lieta kaa sekvences.

 

Nevajag izgudrot divriteni. ;)

Link to comment
Share on other sites

Borja, par sekvencēm zinu un viņas lietoju primary key iegūšanai. Bet rēķina rindu numerācija ir drusku cita padarīšana, tur seqvence neder! 


Reku, tomēr rīts par vakaru gudrāks, uzgāju iekš googles

 

http://logicalread.solarwinds.com/solving-oracle-enq-tm-contention-waits-dr01/#.VHbAKdKUdHU

 

Sataisīju visus trūkstošos foreign key indeksus un loķēšana kā uz burvju mājiena pazuda :D

 

Tomēr gribās lamāties - Nah Oracle, šī krutā datu bāze vispār pieļauj FK bez indeksa??? Nez kurā gadījumā šāda konstrukcija būtu noderīga? Piem iekš firebirda un mysql FK automātiski nozīmē indeksu - taisot FK, index tiek uztaisīts automātiski ja viņa nav!

 

Un ja jau Oracle pieļauj FK bez indeksa, nah šāda konstrukcija netiek korekti apstrādāta, ja vairāki cilvēki ar bāzi vienlaicīgi strādā.... Divas dienas pa kāju meklējot šim sūdam risinājumu....  :rus_roulette:  

Labots - ronalds_
Link to comment
Share on other sites

Mazām tabulām indeksi ir lēnāki par fulskanu.

 

 

 

Tomēr gribās lamāties - Nah Oracle, šī krutā datu bāze vispār pieļauj FK bez indeksa???

Esi apņēmies pabeigt cita cilvēka(-u) iesāktu projektu?

Link to comment
Share on other sites

Esi apņēmies pabeigt cita cilvēka(-u) iesāktu projektu?

 

Jā, esmu.... Un nevis pabeigt, bet uz esošā murga bāzes uzveidot normālu, strādājošu aplikāciju.  Pie tam tā, lai firmas darbība neapstājas. 

 

Zinu ka tas ir sviests.  Bet nu priekšnieks man ir nedaudz pazīstams. Un neviens cits neņēmās (hvz kāpēc :D :D :D ) Un maksā labi, jo viņiem vairs reāli nav izvēles..... 

Skaidrs ka viņiem vajadzēja to iepriekšējo "programmētāju" kas to sviestu ir saveidojis sen kā atlaist, kamēr viss nebija pārākā pakāpē aizlaists.... Bet nu mēs visi esam gudri. Pēc tam.

 

(Дай бы мне бог такой мум как у моей жены потом....) 

 

Nu jau kā gadu čakarējos, izskatās pamazām sāk situācija normalizēties. Jauni, mūsdienām atbilstoši GUI logi pamata funkcijām ir izveidoti, datu bāzes struktūras gļuki tiek laboti. Ir cerība ka viss būs labi!

Šodien ir nenormāls prieks par to ka izdevās lokošanas problēmu atrisināt! Vakar biju galīgi sasļucis.... Bet tagad var virzīties uz priekšu! 

Labots - ronalds_
Link to comment
Share on other sites

Izveido kontu, vai pieraksties esošajā, lai komentētu

Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas

Izveidot jaunu kontu

Piereģistrējies un izveido jaunu kontu, tas būs viegli!

Reģistrēt jaunu kontu

Pierakstīties

Jums jau ir konts? Pierakstieties tajā šeit!

Pierakstīties tagad!
 Share

×
×
  • Izveidot jaunu...