MS SQL Transakcja (nie zadziałała) wrrr

0

Witam,

Mam taki fragment procedury SQL. Generalnie odczytuję jakiś licznik i zwiększam go o 1.

    DECLARE 
        @nr int,
        @year int,
        @pref nchar(5);

    BEGIN TRAN T1;
        SELECT @nr = LSTNUMBER, @pref= PREFIX, @year=LSTYEAR 
            FROM SER.LASTNMBR
            WHERE IDSTATUS = @Typ;

        UPDATE SER.LASTNMBR SET LSTNUMBER = @nr + 1 WHERE IDSTATUS = @Typ;

    COMMIT TRAN T1;
 
SELECT @nr

"Przetworzyłem" nią blisko 300 tyś. rekordów. Ale teraz zdarzyło się, że zostały wygenerowane dwa takie same numery.

Co jest z tym kodem źle?

Czy będzie lepiej jak zrobię:

UPDATE SER.LASTNMBR SET LSTNUMBER = LSTNUMBER  + 1 WHERE IDSTATUS = @Typ;

Ponieważ cały kod jest w transakcji to nie powinno być różnicy.

0

A co to ma wspólnego z transakcją? Pytam serio, ponieważ tu masz gwarancje że, ten update Ci zablokuje rekord i bedziesz mógł to wycofać, pytanie brzmi czy pomiędzy tymi update'ami nie masz czegoś co zmienia lstnumber...

0

Chodziło mi o to aby odczytany numer @nr w selecie nie był zmieniony przez inne wywołanie tej procedury, do czasu gdy nie będzie zrobiony UPDATE.

Chyba powinienem w SELECT użyć WITH (UPDLOCK, ROWLOCK).

Ale znalazłem lepsze rozwiązanie bez transakcji:

 UPDATE SER.LASTNMBR 
		SET @nr = LSTNUMBER = LSTNUMBER + 1 
		WHERE IDSTATUS = @Typ;
2

Nie transakcja zadziałala prawidłowo,tyle że mogłes w tym samym czasie pobrać tą samą wartość. Do zablokowania przy select w twoim wypadku potrzebowaleś HINT XLOCK Mogles to obejsć tak:

DECLARE 
        @nr INT,
        @YEAR INT,
        @pref NCHAR(5);
 
    BEGIN TRAN T1;
        --zablokuj rekord
        SELECT @nr = LSTNUMBER, @pref= PREFIX, @YEAR=LSTYEAR 
            FROM SER.LASTNMBR WITH(XLOCK, ROWLOCK)
            WHERE IDSTATUS = @Typ;
 
        UPDATE SER.LASTNMBR SET LSTNUMBER = @nr + 1 WHERE IDSTATUS = @Typ;
 
    COMMIT TRAN T1;
 
SELECT @nr

1 użytkowników online, w tym zalogowanych: 0, gości: 1