30. oktober 2007 - 14:49Der 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?
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.
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"..
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
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.