[ gewra @ 16.10.2007. 22:52 ] @
Problem je sledeci:

Imam dve tabele, tabelu A koja pored ostalih podataka ima i kolonu bId koja je tipa int i ustvari predstavlja fk kolone id u tabeli B, pri cemu je to i primary key sa identity-jem tabele B.

Imam SP koja treba da upise red u B, izvuce id iz B (ustvari trenutnu vrednost identity-ja) i upise podatke u A zajedno sa izvucenim id-jem.
Ukoliko ne uspe upis u A mora rollback iz B.

Do sada sam imao

begin transaction
insert into B(.......)
if (@@error<>0)
begin
rollback
return -1
end

select @maxBId=max(id) from B

insert into A(....,@maxBId)
if (@@error<>0)
begin
rollback
return -1
end
commit

E sad ovo sve lepo radi dok sp ne pozovem konkurento iz npr 50 niti istovremeno (realni case bi bio oko 500 konkurentnih napada)

Jasno je da naredba select @maxBid=max(id) from B ustvari pravi problem i da zbog nje dolazi do deadlock-a na tabeli B.

Jedno resenje je da spojim ove dve tabele u jednu, ali to zahteva puno refaktorisanja, a pri tome i nije neko programersko resenje. Ima neko drugi predlog?!?!
[ Fedya @ 17.10.2007. 10:14 ] @
Umesto

select @maxBId=max(id) from B

stavi
select @maxBId = SCOPE_IDENTITY()
[ adopilot @ 19.11.2007. 08:42 ] @
Probaj dodati na kraju prve transakcije

SET @maxBId=@@identity

gdije je @@identity sistemska varijabla koja zapisuje zadnji ubačeni PK u neku tablicu.

Lijep pozdrav
[ Teks @ 19.11.2007. 17:15 ] @
teoretski

SET @maxBId=@@identity

može da ne vrati ono što očekujemo (vrati PK od neku druge tabele sa kojom radi neko drugi)
ovo bi bilo interesantno probati simulirati ...

držite se što je rekao Fedya i nećete pogrešiti

select @maxBId = SCOPE_IDENTITY()
[ M E N E @ 20.11.2007. 12:24 ] @
da, SCOPE_IDENTITY() je bolje resenje...