Avatar billede mat Nybegynder
07. december 2004 - 15:32 Der er 20 kommentarer og
2 løsninger

"sikre" transaktioner?

Hej

Jeg sidder og arbejder med nogle transaktioner og har i den henseende et par spørgsmål om samtidighed.

Mine tabeller er af typen InnoDB og så vidt jeg har forstået er disse transaction safe i deres implementering.
Er det korrekt forstået?

Jeg har derudover et tilfælde hvor jeg først skriver til databasen, derefter henter information fra denne transaktion og efterfølgende skriver igen - alt dette må ikke kunne "forstyrres".

Jeg har så fundet følgende afsnit på mysql.com

"If the connection has autocommit enabled, the user can still perform a multiple-statement transaction by starting it with an explicit START TRANSACTION or BEGIN statement and ending it with COMMIT or ROLLBACK."

Er det er at forstå som at, hvis jeg explicit skriver:

START TRANSACTION
# skriv
# læs
# skriv
COMMIT

Så er dette sikkert fra problemer med at der kan skrives mens jeg læser og inden jeg skriver anden gang?

Eller er hele dette scenarie bare tåbeligt, og bør omskrives?

På forhånd tak for hjælpen
mvh mat
Avatar billede arne_v Ekspert
07. december 2004 - 15:39 #1
InnoDB tabeller understøtter transaktioner d.v.s. at du kan sikre dig at
et antal opdateringer enten alle udføres eller ingen udføres.
Avatar billede arne_v Ekspert
07. december 2004 - 15:40 #2
Jeg tror at du skal læse lidt om transaction isolation level.

Hvis du bruger transaction isolation level serializable så vil duihvertfald
opnå det du vil.
Avatar billede mat Nybegynder
07. december 2004 - 16:32 #3
Jeg skal være den første til at indrømme at jeg ikke ved meget om MySQL. So bare with me :)

Men skal det forstås sådan at transaktioner som du beskriver dem, i dit første indlæg,  ikke har noget med samtidighed at gøre? Men at de bare en en rollback funktion hvis et eller andet glipper undervejs? (Og dermed er mit "start transaction .... commit" overflødigt?)

Jeg har kigget på isolation level men jeg forstår ikke rigtigt hvordan jeg bruger det?

Vil det være:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZED
START TRANSACTION
...
...
COMMIT

Eller hvorledes?

(undskyld hvis jeg spørger dumt).

mvh mat
Avatar billede arne_v Ekspert
07. december 2004 - 16:47 #4
Transaktioner styrer også muligheden for forstyrrelse mellem uafhængige transaktioner,
men hvordan den styrer det afhænger af transaction isolation level.
Avatar billede arne_v Ekspert
07. december 2004 - 18:12 #5
Læs evt. http://www.iona.com/support/docs/e2a/asp/5.0/j2ee/DevelopGuide/html/Jta-Bas5.html?test=yes

(ignorer den nederste halvdel medminder du tilfældigvis er interesseret
i IONA J2EE app-server)

Den forklarer hvad transaction isolation level går ud på.
Avatar billede mcgoat Nybegynder
07. december 2004 - 18:17 #6
Sådan som jeg har forstået og forklaret det:

START TRANSACTION
# skriv
# læs
# skriv
COMMIT

Så bliver intet af:
# skriv
# læs
# skriv
udført før COMMIT bliver kørt... Så hvis der sker en fejl der så sker intet.
Avatar billede mcgoat Nybegynder
07. december 2004 - 18:18 #7
det sker kun "virtuelt", det er først når COMMIT bliver kørt at det egnetlig bliver smidt i databasen.
Avatar billede arne_v Ekspert
07. december 2004 - 18:20 #8
Det er en lidt forsimplet version.

Det forudsætter at transaction isolation level ikke er read uncommitted.

(hvad den dog heller ikke bør være)
Avatar billede mat Nybegynder
07. december 2004 - 20:54 #9
Hej igen

Undskyld det lige tog mig lidt tid at vende tilbage.

Jeg vil læse dit link Arne, tak for det.

Men vil ovenstående betyde at såfremt transaction level ikke er read uncommitted i en evt opsætning, så burde jeg være sikker med start transaction/commit løsningen, uden nødvendigvis at explicit sætte isolation level til serialized?

Begge løsninger virker naturligvis ved vore transaktion, men af hvorvidt de også sikrer at der ikke sker uhensigtsmæssigheder ved samtidig aktivitet, ved jeg ikke. Har i evt et forslag til hvordan man rent faktisk tester den slags?..det er unægtelig en kende uberegneligt at sige: "3, 2, 1 submit" :)

Hvis jeg skal forklare den konkrete problemstilling lidt nøjere så er det:
Vi knytter en avatar med en række parametre til en bruger. Denne avatar har sin egen tabel og det har brugeren også. Idet vi opretter avataren tildeles den et 'id' (autoincremented), det er dette 'id' vi henter op igen for at skrive det ned i brugerens tabel idet han oprettes.

Jeg ved ikke om det ganske enkelt bare er en skidt måde at gøre hele det her sjask på? Og der er for så vidt ikke nogen grund til at vi ikke kan have avatarens informationer i samme tabel som brugeren, men det er den bare ikke pt.

Mange mange tak for jeres hjælp so far :)

mvh mat
Avatar billede arne_v Ekspert
07. december 2004 - 20:58 #10
Det er en skidt måde.

INSERT i avatar tabellen
INSERT i bruger tabellen og angiv LAST_INSERT_ID() for avatar id

bør være måden at gøre det på.
Avatar billede arne_v Ekspert
07. december 2004 - 21:00 #11
Ellers mener jeg at du skal helt op på serializable for at få det til at virke.

Ford det du skal er at sikre at
  SELECT MAX(id) FROM avatar
returnerer det samme under hele tranasktionen - du skal undgå phantom reads.
Avatar billede arne_v Ekspert
07. december 2004 - 21:01 #12
read committed sikrer at du ikke læser data som ikke er committed
endnu, men det er ikke nok i dit tilfælde
Avatar billede mat Nybegynder
07. december 2004 - 21:06 #13
Ja jeg havde lidt på fornemmelsen at det var et sidespor...mange tak.

Jeg har vist fået hvad jeg efterlyste her, så hvis i smider et svar deler jeg jeres velfortjente point ud.

Endnu engang tak.

mvh mat
Avatar billede arne_v Ekspert
07. december 2004 - 21:07 #14
svar
Avatar billede arne_v Ekspert
07. december 2004 - 21:08 #15
Men læs lidt om transaction isolation level. Det er et must at kende
for enhver programmør som bruger databaser.
Avatar billede mat Nybegynder
07. december 2004 - 22:29 #16
jeps det vil jeg gøre, "mcgoat" vil du også have en slat point for din deltagelse?
Avatar billede mcgoat Nybegynder
07. december 2004 - 23:37 #17
tja, mjo.. ok da... hehe...
Avatar billede mat Nybegynder
08. december 2004 - 11:32 #18
Arne dit link bliver ved med at påstå at jeg ikke tillader cookies uanset hvad jeg gør, (så jeg kiggede her http://www.devshed.com/c/a/MySQL/Storage-Engine-Table-Types/6/). Men nu gør vi det på den måde at:

sætter session transaction isolation level til serialized
starter transaction
inserter avatar
inserter last_insert_id() i bruger
committer

Det virker ihvertfald umiddelbart, så må vi se om det holder :)

I har forresten ikke et link eller to til hvordan man tester for samtidighed i virkelighedens verden?

Brug nu jeres point fornuftigt!
Avatar billede arne_v Ekspert
08. december 2004 - 11:45 #19
Da last_insert_id() er per connection, så virker den selv uden transaktioner !
Avatar billede mat Nybegynder
08. december 2004 - 11:48 #20
oki, thx :)
Avatar billede arne_v Ekspert
08. december 2004 - 11:48 #21
Avatar billede arne_v Ekspert
08. december 2004 - 11:51 #22
http://www.databasejournal.com/features/mysql/article.php/3393161

viser endda lidt om hvordan man kan teste det
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
Computerworld tilbyder specialiserede kurser i database-management

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