Avatar billede rust10 Nybegynder
18. april 2004 - 00:20 Der er 26 kommentarer og
1 løsning

lidt forståelse af OleDbTransaction's

Når jeg benytter mig af OleDbConnection.BeginTransaction(), så starter jeg en transaction på selve SQL serveren? Så hvis jeg har to applikationer der tilgår samme database, så kan jeg komme uden om nogle samtidigheds problemer ved at benytte mig af transaktioner, og regulere IsolationLevel efter hvad jeg skal bruge?

Når jeg så læser om de forskellige IsolationLevel's på MSDN får jeg f.eks. ved Serializable afvide:
A range lock is placed on the DataSet, preventing other users from updating or inserting rows into the dataset until the transaction is complete.

Og hvis jeg læser om det i dokumentationen til den MS-SQL2000 database jeg bruger, får jeg en lidt anderledes beskrivelse. Men hvis jeg har fattet rigtigt, at dette transaction snask startes på selve SQL serveren, så skal jeg vel regne med beskrivelsen som serveren kommer med, eller er jeg galt på den?
Avatar billede guidmaster Nybegynder
18. april 2004 - 00:23 #1
Hvorfor er det lige at du bruger OleDb og ikke den dataprovider der er beregnet til SQL Server?

Men når du nu bruger SQL server, så vil jeg gå efter den dokumentation der er i bol.
Avatar billede arne_v Ekspert
18. april 2004 - 00:23 #2
Ja - transaktioner håndteres på database serveren.

De to beskrivelser er forhåbentligt ikke decideret modstridende.
Avatar billede rust10 Nybegynder
18. april 2004 - 09:01 #3
Krav at jeg bruger OleDbProvider for at SQL serveren kan udskiftes let uden ændringer i koden.
Nej, ikke direkte modstridende, bare flere restriktioner er nævnt på SQL serveren. Og det der med DataSet's i MSDN's beskrivelse, fik mig til at tro at det måske kun var noget transactions styring, der ikke direkte havde noget med databasen serveren at gøre.

Da jeg blev undervist i Java lærte jeg, at man bare implementeret sin database klasse med et singleton pattern og bankede synchronized på alle metoder der manipulerede med databasen, og alle samtidigheds problemer var løst.
Men er problemerne ikke kun løst hvis dette er den eneste klasse der tilgår disse tabeller i databasen, man er vel ikke sikret hvis der er to applikationer der tilgår samme tabeller i databasen. Men ville være det hvis man brugte transactioner?
Og er der noget skidt ved at benytte transactioner frem for singleton/lock i c# hvis man ved man er alene om databasen?
Avatar billede arne_v Ekspert
18. april 2004 - 09:37 #4
singleton og synchronized sikrer mod problemer i flere tråde i samme app. Det
kræver at singleton klassen er den eneste som bruger database. Det
garanterer ikke mod andre problemer hvis samme app køres flere gange
eller andre apps bruger databasen.

Du kan også bruge singleton og lock(this) {} i C# helt tilsvarende.

Hvis din app er helt ene om databasen, så svarer singleton + låsning til
transaktion med isolation level serializable og en meget dårlig database server.

En god database server vil tillade transaktioner som ikke konflikter at
blive udført parallellt selv med isolation level serializable.

I de fleste tilfælde vil det være sikrere og hurtigere at bruge database
transaktioner.
Avatar billede rust10 Nybegynder
18. april 2004 - 09:55 #5
Kanon var også det jeg havde forstillet mig.

Lige en sidste ting som egentligt ikke har så meget med det at gøre. Men hvis jeg har en Web Service med en række metoder der henter eller manipulere med databasen igennem en database klasse. Så har jeg et multi-tråds miljø?

Jeg forstiller mig af web serveren på en eller anden måde opretter en ny tråd for hver connection der er til Web Servicen.
Men hvis jeg har implementeret min database klasse med singleton, og jeg åbner databasen forbindelsen i konstruktøren hvor jeg aldrig lukker den igennem klassen.
Betyder det, at jeg aldrig har mere end én connection til databasen, lige meget hvor mange der tilgår min Web Service på samme tid?
Eller får hver tråd en helt ny instans af Web Servicen og arbejde med?
Avatar billede rust10 Nybegynder
18. april 2004 - 09:58 #6
Hov, lige en sidste ting.. Transactioner, er det noget alle databaser kan, eller ved at benytte mig af transactioner reducerer jeg antallet af databaser jeg vil kunne benytte, lige som hvis jeg bruger stored procedures?
Avatar billede rust10 Nybegynder
18. april 2004 - 10:12 #7
læg også lige et svar næste gang du svare mig
Avatar billede arne_v Ekspert
18. april 2004 - 10:12 #8
Enhver fornuftig web servive (SOAP over HTTP) implementation vil være multithreaded.

Hvis din database klasse er en singleton, så bliver der kun en connection.
Avatar billede arne_v Ekspert
18. april 2004 - 10:15 #9
De fleste database understøtter transaktioner. Eneste lille krølle jeg kan komme i
tanke om er at man med MySQL skal brugeg InnoDB tabeller og ikke MyISAM tabeller
for at få transaktions support.

De fleste databaser understøtter også stored procedures (dog ikke MySQL endnu). Men
der er den komplikation at de er forskelligt implementeret. Du kan ikke bare
flytte en stored procedure mellem MS SQLServer og Oracle DB selvom begge
supporterer stored procedures.
Avatar billede arne_v Ekspert
18. april 2004 - 10:15 #10
svar
Avatar billede rust10 Nybegynder
18. april 2004 - 20:28 #11
Jeg havde den (forkerte?) opfattelse af når jeg satte isolationlevel til serializable, som er det højeste niveau, at man faktisk blokkerede for alle andre transaktioner indtil den ens transaktion var fuldført. Men efter at jeg blev spurgt om, hvad præcis det er jeg låser med dette isolation niveau, er jeg blevet i tvivl, og synes ikke jeg kan finde noget information der beskriver det præcist.

Jeg kunne godt forstille mig at, man kun sætter en lås om det data man selv berøre. Dvs. at låsen måske kun er omkring de rækker, i de tabeller man piller ved. I stedet for at låse hele databasen som jeg først havde opfattet.
Avatar billede arne_v Ekspert
18. april 2004 - 20:32 #12
transaction isolation level serializable betyder at resultaterne skal
blive som om transaktionerne var lavet en af gangen.

Databasen kan optimere som den vil sålænge den kan garantere dette.
Avatar billede arne_v Ekspert
18. april 2004 - 20:34 #13
Avatar billede rust10 Nybegynder
18. april 2004 - 21:14 #14
Hmm, der er et eller andet der ikke står helt klart for mig, ang. hvordan de her transaktioner fungere.

Men som jeg har forstået dette:

Hvis man forstiller sig 2 transaktioner t1 og t2.
- t1 startes med Connection.BeginTransaction(IsolationLevel.Serializable) i min c# kode klokken 0:00.
- t2 startes på samme måde klokken 0:01.
- Fordi t1 er sat til IsolationLevel.Serializable og stadig ikke er afsluttet, kan t2 ikke starte med det samme, og må vente.
- Fordi jeg synes, det er helt vildt smart lige at kopiere en floppy disk over på min harddisk før jeg commiter t1 (som jeg antager afslutter t1), tager denne transaktion 5mins.
- t2 kan derfor nu først startes klokken 0:05.

Er det rigtigt forstået at jeg har blokeret for t2 i 5minutter?
Og hvad er det jeg blokere, hele databasen, kun de tabeller t1 arbejder på, eller kun de rækker t1 arbejder på?
Avatar billede rust10 Nybegynder
18. april 2004 - 21:24 #15
Efter lige at have læst dit svar igennem et par gange.. Mener du så at Serializable betyder at, resultatet af afviklingen af t1 og t2 skal være det samme som at de blev afviklet en af gangen. Men at Serializable ikke er en definition på hvordan præcis databasen håndtere at udføre dette, så det kan variere fra DB til DB, men samme resultat er garanteret.
Avatar billede arne_v Ekspert
18. april 2004 - 21:27 #16
Ja.

Transaction isolation level serializable garanterer mod dirty reads, non repeatable
reads og phantom reads.

Det svarer på mere jævnt dansk til at "resultaterne er som hvis transaktionerne
blev udført en af gangen".

Hvordan databasen opnår det resultat må den selv om.
Avatar billede arne_v Ekspert
18. april 2004 - 21:28 #17
Hvis vente tiden kan blive 5 minutter, så skal du ikke bruge transaktioner,
men noget andet f.eks. versioning.
Avatar billede rust10 Nybegynder
18. april 2004 - 21:36 #18
Okay, så lige et bonus spørgsmål :)

Hvis jeg nu benytter mig af SELECT @@IDENTITY, i et multiuser/tråd miljø. Så er jeg garanteret, at den indeholder det nummer som jeg jeg har genereret tidligere inde i samme transaktion.

Performance mæssigt, er det en katastrofe at benytte sig af denne høje isolation level tit, eller betyder det ikke så meget?
Avatar billede rust10 Nybegynder
18. april 2004 - 21:38 #19
Det jeg fiskede lidt efter med eksemplet, var bare om jeg totalt blokerede databasen ved at benytte den isolations level, eller om alt andet trafik som egentligt ikke er relateret til min transaktion bare fortsætter urørt.
Avatar billede arne_v Ekspert
18. april 2004 - 21:38 #20
@@IDENTITY er connection specifik og giver den sidste identity genererer
for connectionen. Uanset transaktion.
Avatar billede arne_v Ekspert
18. april 2004 - 21:40 #21
Hvis du bruger SQLServer 2000 så kan det anbefales at bruge SCOPE_IDENTITY()
(forskellen er at den overskrives ikke hvis du kalder en stored procedure
som indsætter i en anden tabel).
Avatar billede arne_v Ekspert
18. april 2004 - 21:42 #22
Ja - højere isolation level sænker performance, så principielt vil man køre
med den laveste isolation level som stadig garanterer at ens applikation
virker.

En seriøs database bør performe nogenlunde selv med isolation level serializable.
Avatar billede rust10 Nybegynder
18. april 2004 - 21:48 #23
re: @@IDENTITY er connection specifik og giver den sidste identity genererer
for connectionen. Uanset transaktion.


Ah det er rigtigt, det har du sagt før.

Men når jeg opretter min connection i konstruktøren på min database klasse, og denne klasse bliver tilgået fra web metoder på min web service. Så er det vel ikke helt utænkeligt at med korrekt timing, så bliver der startet to metoder omkring samme tid, som hvert opretter en ny identity, og at der går kluder i hvilke tal der returneres fra databasen.
Jeg benytter selv scope_identity() og SP's til dette, så er vel helt uden om problemet, jeg tænker bare..
Avatar billede arne_v Ekspert
18. april 2004 - 21:52 #24
To tråde der kører parallelt skal bruge hver sin connection.

Ellers får du problemer - transaktioner eller ej.

Og med forskellige connections er der ingen problem med @@IDENTITY.
Avatar billede rust10 Nybegynder
18. april 2004 - 21:55 #25
Vil det sige at tråd1 ikke får tilgang til databasen før tråd2 er færdig, når de deler den samme connection i c# klassen?
Avatar billede arne_v Ekspert
18. april 2004 - 21:57 #26
Nej - det betyder at du får fejl.

(medmindre du selv via lock sikrer sig at den ene er færdig før den anden starter)
Avatar billede rust10 Nybegynder
18. april 2004 - 21:59 #27
okies.

Du skal have mange tak for din tålmodighed med alle mine ekstra spørgsmål, Trer og dig har lært mig mange ting om database/c# her på det sidste hehe
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester