Mam wymóg utworzenia procedury składowanej, która emuluje sekwencję TSQL. Oznacza to, że zawsze daje rosnącą wyraźną wartość całkowitą przy każdym połączeniu. Ponadto, jeśli podana jest liczba całkowita, powinna zwrócić tę wartość, jeśli nigdy nie było wyniku większego lub następnej najwyższej dostępnej liczby całkowitej. Oczywiste jest, że może być wielu klientów dzwoniących do tego SP w tym samym czasie.
Biorąc pod uwagę tabelę MetaInfo z kolumnami MetaKey varchar (max) i MeatValueLong bigInt. Oczekuje się, że wiersz z MetaKey „Internal-ID-Last” będzie zawierał ostatnią najwyższą przypisaną wartość. Utworzyłem następującą procedurę przechowywaną:
CREATE PROCEDURE [dbo].[uspGetNextID]
(
@inID bigInt
)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
UPDATE MetaInfo WITH (ROWLOCK)
SET MetaValueLong = CASE
WHEN ISNULL(MetaValueLong,0) > @inID THEN MetaValueLong+1
ELSE @inID+1
END
WHERE MetaKey = 'Internal-ID-Last'
SELECT MetaValueLong
FROM MetaInfo
WHERE MetaKey = 'Internal-ID-Last'
COMMIT TRANSACTION
END
Moje pytanie brzmi po prostu, czy ta procedura przechowywana działa zgodnie z oczekiwaniami (wszystkim osobom wywołującym zostanie przypisany unikalny wynik)?
źródło
Odpowiedzi:
Spojrzałem i same stwardnienie rozsiane oferują rozwiązanie bez blokad
http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx
Jest to prosta aktualizacja bez wskazówek blokujących, ale mówią, że blokuje / zakleszczenia.
Nie ma też wiele na temat SO.
Byłbym skłonny dodać UPDLOCK do ROWLOCK (zgodnie z „tabelą jako kolejką” (SO), ale bez READPAST). Zwiększy to izolację w przypadku, gdy drugi proces rozpocznie czytanie.
Jednak fakt, że wszystkie twoje procesy chcą czytać / zapisywać ten sam wiersz, sam siebie zgaduję. READPAST umożliwia bezpieczną współbieżność, ale w tym przypadku jest bezużyteczna.
Uwaga: możesz użyć klauzuli OUTPUT zamiast drugiej opcji wyboru, a następnie nie potrzebujesz transakcji.
HTH ...
źródło
Brakuje następujących rzeczy
Tak, powinien spełniać twój warunek. Gdy takie sytuacje pojawią się w transakcjach, tworzy wiele wystąpień, a następnie wszystkim dzwoniącym zostanie przypisany unikalny wynik
źródło
Bardziej skalowalnym rozwiązaniem, które nie wymaga serializacji jest:
źródło