Wykonywanie transakcji w MS SQL

0

Załóżmy, że mamy taką tabelę T, która ma pola:
ID - int, identyfikator nadawany automatycznie przy dodawaniu rekordów
A - varchar
B - varchar

Wartości A i B mogą się powtarzać, a ID jest niepowtarzalny i nadawany automatycznie (kolejne numery):

Załóżmy, że chcemy, żeby w polu B był identyfikator (nie ważne, czemu to ma służyć, chodzi o przykład), mam taki pomysł:

-- Dodanie wpisu ze znakiem charakterystycznym, identyfikator rekordu nie jest znany
insert into T (A,     B)
       values ('qwe', '<->')

-- Zdefiniowanie zmiennej do przechowania identyfikatora
define @I varchar

-- Znalezienie numeru ID wpisu ze znakiem charakterystycznym
select @I = ID from T where B = '<->'

-- Zamiana znaku charakterystycznego na identyfikator ze zmiennej @I
update table t set B = @I where B = '<->'

-- W tym miejscu mamy uzupełnione pole B, w którym jest identyfikator rekordu

Gdyby założyć, że w danej chwili tylko jeden klient wykonuje transakcję, to nie byłoby żadnego błędu.

Natomiast w przypadku wykonania ten procedury przez dwóch klientów naraz będzie błąd w poniższej sytuacji przy założeniu, że serwer wykonuje polecenia w dwóch wątkach:

A: insert into T (A,     B)
          values ('qwe', '<->')

B: insert into T (A,     B)
          values ('asd', '<->')

-- W tym miejscu w tabeli T są dwa wiersze zawierające znak charakterystyczny zamiast identyfikatora


-- Poniższe instrukcje nie będą wykonane u obu klientów, bo "select" zwróci dwa rekordy zamiast jednego
A: define @I varchar
A: select @I = ID from T where B = '<->'
B: define @I varchar
B: select @I = ID from T where B = '<->'


-- Nastąpi zmiana znaku zarówno dla rekordu z polem A o wartości 'qwe', jak i 'asd'
A: update table t set B = @I where B = '<->'


-- Poniższa instrukcja nie zostanie wykonana z powodu braku znaku charakterystycznego w tabeli
B: update table t set B = @I where B = '<->'

Czy rzeczywiście może dojść do błędu, czy serwer SQL przeczeka, aż jedna procedura będzie wykonana do końca, a potem uruchomi drugą i wtedy obie transakcje zostaną wykonane bezbłędnie (zgodnie z założeniami)?

0

Jeżeli dobrze zrozumiałem, to powinno być tak:

update table t set B = ID where B = '<->'

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