21. maj 2003 - 09:57Der er
22 kommentarer og 3 løsninger
Stored Procedures i Transaction
Hej
Jeg sidder og er ved at prøve at finde en løsning på hvordan jeg kan lave noget DB persistens på en klasse struktur med nedarvning i flere lag.
f.eks. Person --> Kunde --> Privatkunde
Hver af disse skal være ansvarlig for at opdatere sine egne data i databasen og derfor laver jeg en stored procedure for hver der tager netop den klasses data som parametre.
Dette gør at jeg får tre kald til databasen en p. stored procedure.
Dette ville jeg gerne undgå.
Derfor tænkte jeg om det var muligt at pakke de tre stored procedure kald ind i én transaction.
Vil dette resultere i ét kald til databasen eller vil jeg være ligeså dårligt stillet som med tre individuelle kald ??
Det vil altid vaere hurtigere overall at lave 1 kald istedet for flere da du spare noget netvaerkstid, du skal dog bare vaere opmaerksom paa at dine tabller saa ogsaa er laast det laengere, f.eks hvis du vil lave 10.000 inserts indivduelt, saa kan andre queries tilgaa dine tabeller mellem disse inserts, men hvis du tager dem i en mundfuld vil det gaa hurtigere, men dine tabeller vil vaere laast indtil alle 10.000 records er indsat. Jeg finder selv at loftet gaar ved en 20-25.000 inserts/updates i et kald for at det er bedre at lave individuelle, saa angaaende dine 3, saa vil jeg sige, smid dem bare i en query
der er bare et lille problem her, som gør at jeg ikke kan smide dem i én Query. Det er p.g.a. at de klasser jeg omtaler skal være rent black box d.v.s. at du ikke skal/må vide no get om hvad der sker i den klasse du nedarver fra. Derfor skal de alle gerne ha' hver deres stored procedure, men jeg vil helst begrænse antallet af kald til databasen til én.
Defor overvejer jeg en transaction, men spørgsmålet er om det resulterer i ét eller flere kald.
Hvad med dynamisk at bygge et t-sql script op hvor du laver de kald der skal til? Nu ved jeg ikke hvad du bruger af udviklingsværktøjer, men fx. i ADO.NET kan du sagtens give flere t-sql linier kode til en SqlCommand, ligesom i Query Analyzer. Så får du kun et kald til serveren der skal fortolkes, men med kald af fx. 3 stored procedures. Eks.:
Jeps det er netop de to ting jeg tænker på, det der med dynamisk opbygning af SQL er lige vand på min mølle da jeg nemt kunne opbygge det så det hele bliver fuldt automatiseret ud fra min klassemodel.
By the way jeg bruger .net som udviklingsværktøj.
Med hensyn til det sidste med transaction så er jeg stadig i tvivl om det i forhold til hvor mange kald til DB det giver og hvilken performance.
Hvis du dynamisk konstruerer et t-sql "script" som du så giver til SqlCommand, så har du jo kun eet netværkskald til serveren, og hvis du samtidig bruger stored procedures i scriptet som hovedpart, så vil det sikkert køre fornuftigt da stored procs jo er precompiled. Ellers må du generere nogle forskellige scripts som de ville se ud i praksis og så køre en analyse på dem med query analyser for at finde evt. flaskehalse.
Husk altid at lave små transactioner. Hellere mange små sp's end en stor!
den er fjong denne her som mjohansen siger... sql = new SqlCommand("begin transaction exec proc1 exec proc2 exec proc3 commit transaction", o.s.v.
mjohansen-> en dynamisk sp er ikke precompiled ;O) (men det vidste du sikkert)
Og til sidst, min egen personlige erfaring hehe... Det betyder absolut intet (+-1ms) om du laver 3 kald til basen eller 1 sålænge du bruger samme connection (eller 3 der allerede er åbne)
Ja det vil vel være bedre at lave tre kald til tre stored procedures end det er at lave en som så indeholder en masse sammenligningslogik for at finde ud af hvad den skal opdaere på.
MEN hvis vi nu forestiller os situationen i forbindelse med en insert af en record hvor data kommer fra tre klasser og dermed via tre SP'er så er det lidt tricky da den første skal lave en indert og de næste en update på den netop indsatte record :-/
Nu er der ikke tale om dynamisk SP, men dynamisk opbyggede SQL strenge som udføres via et command object.
farouche-> ja og hvis det er tilfældet med dynamiske sql strenge er der intet at hente ved sp's overhovedet - tværtimod. (medmindre du tilføje 'with recompile')
Mht. en efterfølgende update, hmm kunne du ikke poste lidt af den sql du bruger de ter måske nemmere at se logikken i det så :O)
mjohansen-> nu er en transaction jo ganske relativ, men jeg kan fortælle dig at jeg har testet sqlserver med 28000inserts/sec og 100 samtidige connections. Hastigheden var uændret da jeg sænkede connections til 10!
stored procs bliver precompiled, derfor er tabelnavne og kolonnenavne statiske. Så du må gøre op med dig selv, hvor statisk/dynamisk dine sql-transaktioner har behov for at være.
Du må analysere helt igennem hvad du får behov for. Måske kan du skrive nogle gode stored procs til en del af det, og så "lime" det sammen med dynamisk genereret sql.
¨Det er simpelthen fordi jeg kun ønsker at opdatere de fields der er sat til at skulle ha en ny værdi.
Alle andre vil blive smidt i SP'en med værdien null (det er fordi jeg kan risikere en utilsigtet overskrivning af værdier pga mit nedarvningshieraki)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.