Avatar billede flyver23 Nybegynder
30. oktober 2007 - 14:49 Der er 10 kommentarer og
1 løsning

Låsning af database.

Hejsa.
Jeg har en C# applikation som anvender sql server database.
Når jeg opretter en ny post i databasen skal jeg bruge denne post´s autogenerede ID.

Jeg gør følgende:
Transaction.begin

Insert INTO Xxxxxxx

SELECT TOP 1 ID FROM Xxxxxx

Transaction.commit

Jeg låser databasen for at sikre at der ikke oprettes nye poster mellem min INSERT og min SELECT.

Hvis jeg debugger min c# applikation og pauser mellem INSERT og SELECT kan jeg dog fra en anden maskine stadig afvikle funktionen og ændre i data så min SELECT giver forkert ID retur.
Jeg anvender IsolationLevel.Serializable i min transaction. Jeg troede at denne måde sikrede imod at der kunne afvikles flere transaktioner til databasen samtidigt.
Mine commit og Rollback funktioner virker helt efter hensigten.
Hvad gør jeg galt?

Vh Flyver23
Avatar billede erikjacobsen Ekspert
30. oktober 2007 - 14:52 #1
Du skal bruge @@identity eller @@scope_identity. Google holder på at være din ven :)
Avatar billede hrc Mester
30. oktober 2007 - 15:01 #2
Kig i øvrigt dette link. Her er masser af eksempler og en fin beskrivelse af hele TSQL (for 2000'eren)

http://msdn2.microsoft.com/en-us/library/aa299742(SQL.80).aspx

Med den ene af de to ovennævnte @@'er kan du hente ID'et uden at behøve låse databasen.
Avatar billede nielle Nybegynder
30. oktober 2007 - 15:06 #3
Transactioner er ikke i sig selv en garanti for at andre programmer ikke kan komme til basen i mellemtiden.

De er udelukkende tænkt til at samle et antal SQL kommandoer i et samlet hele, sådan at man kan sikre sig at de alle sammen er gennemført, eller alle sammen kan rulles tilbage samlet.
Avatar billede a1a1 Novice
30. oktober 2007 - 16:06 #4
skal du "bare" have det nye id?

så er:
insert into table (a,b) values (1,2)
select @@identity

perfekt, det er for hver connection den "kommer" dvs. det er den det rigtige, uanset om der kommer en imellem; select top 1 vil kunne lave en "fejl" hvis der er 2 eller flere samtidige "requests"..

;o)
Avatar billede a1a1 Novice
30. oktober 2007 - 16:09 #5
og du har ikke bruge for din:
transaction.begin/end
da det jo foregår i mssql'en er kun en sætning (der er ikke noget at "rolle" back")
Avatar billede a1a1 Novice
30. oktober 2007 - 16:15 #6
som nielle siger: er transactions ment/lavet til at sørge for at alle "aftaler"/sql kommandorer bliver afviklet...

det typiske eksempel er en bank:

begin trans
insert into tbl_bank (account,amount)values(@account,@value)
if select amount from tbl_bankroll) where account=@account and amount > @value)
begin

transcommit
end
else
begin
rollbacktrans
end

Psoudokode...;o)
Avatar billede flyver23 Nybegynder
31. oktober 2007 - 17:47 #7
ErikJacobsen og HRC har i samarbejde været med til at løse mit problem, og svarede hurtigst.
Hvis i smider et svar deler jeg point´s..

Tak for hjælpen.
Vh Flyver23
Avatar billede erikjacobsen Ekspert
31. oktober 2007 - 18:13 #8
Ingen point til mig, tak.
Avatar billede flyver23 Nybegynder
05. november 2007 - 08:25 #9
Mangler et svar fra HRC
Avatar billede flyver23 Nybegynder
20. december 2007 - 17:30 #10
Ingen svar fra HRC, så point går til a1.
Spm skulle jo lukkes inden jul.
God jul og tak for hjælpen.
Vh flyver23
Avatar billede a1a1 Novice
20. december 2007 - 23:09 #11
sæl god jul, håber at du kan bruge 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