Tożsamość SQL (autonumber) jest zwiększana nawet po wycofaniu transakcji
Mam transakcję. Net z wstawką SQL do bazy danych SQL Server 2005. Tabela ma klucz podstawowy tożsamości.
Gdy wystąpi błąd w transakcji, wywoływany jest Rollback()
. Wstawki wiersza są odwrócone poprawnie, jednak przy następnym wstawieniu danych do tabeli tożsamość jest zwiększana tak, jakby cofnięcie nigdy nie miało miejsca. Więc Zasadniczo istnieją luki w sekwencji tożsamości. Czy jest jakiś sposób, aby metoda Rollback()
odzyskała brakującą tożsamość?
8 answers
Jeśli się nad tym zastanowić, numer auto-increment nie powinien być transakcyjny. Jeśli inne transakcje musiały poczekać, aby sprawdzić, czy auto-numer zostanie użyty lub "wycofany", zostaną zablokowane przez istniejącą transakcję przy użyciu auto-numeru. Na przykład, rozważmy mój kod psuedo poniżej z tabelą a, używając pola auto-number dla kolumny ID:
User 1
------------
begin transaction
insert into A ...
insert into B ...
update C ...
insert into D ...
commit
User 2
-----------
begin transaction
insert into A ...
insert into B ...
commit
Jeśli transakcja użytkownika 2 rozpocznie się milisekundę po transakcji użytkownika 1, wtedy ich wstawienie do tabeli A będzie musiało poczekaj, aż cała transakcja użytkownika 1 zostanie zakończona, aby sprawdzić, czy użyto auto-numeru z pierwszej wstawki do A.
To jest funkcja, nie błąd. Polecam użycie innego schematu do generowania auto-numerów, jeśli potrzebujesz, aby były ściśle sekwencyjne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-28 15:32:42
Jeśli zależy ci na tym, że twoje wartości tożsamościowe są puste, to tak - robisz to źle. Całość klucza zastępczego to ma mieć żadnego znaczenia biznesowego .
I, nie, nie ma sposobu, aby zmienić ten behaivor (pomijając zwijanie własnego autoincrement, i ponosząc konsekwencje wydajności blokowania innych wstawek).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-12 01:11:21
Masz luki w sekwencji, jeśli DELETE
wiersz też.
Sekwencje muszą być unikalne, ale nie muszą być sekwencyjne. Fakt, że są one monotonicznie rosnące jest tylko fuksem realizacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-11 23:56:53
Wszystkie inne plakaty, które mówią, żeby się tym nie martwić, i że ty powinieneś dostać luki, mają rację. Jeśli numer ma znaczenie biznesowe, a to znaczenie nie łączy się z lukami, nie używaj kolumny tożsamości.
FYI, jeśli z jakiegokolwiek powodu chcesz usunąć luki, większość baz danych ma sposób, aby przekierować automatyczną numerację do wybranego numeru. To wrzód na dupie, a jeśli uważasz, że potrzebujesz robić to regularnie, zdecydowanie nie powinieneś używać pole autonumber / identity, jak wspomniano powyżej. Ale oto kod do zrobienia tego w SQL server:
DBCC CHECKIDENT('Product', RESEED, 0)
Ustawia, że tabela produktów zaczyna się od 1 (chociaż jeśli masz rekordy w tabeli, to oczywiście pomija wartości ID, które są już zajęte.) Inni dostawcy RDBMS mają swoją własną składnię, ale efekt jest mniej więcej taki sam, więc poszukaj "reseed identity" lub "reseed autonumber" w plikach pomocy systemowej lub internetach.
Jeszcze raz: to jest na specjalne okazje, nie regularne stosowanie. Nie umieszczaj tego w procedurze składowanej i nie zmuszaj nas do tego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-14 02:15:24
Z tego co wiem wiersze do wstawiania twierdzą, że autonumber i po wycofaniu ta liczba jest tracona na dobre. Jeśli zależy ci na tym, że autonumber jest w sekwencjonowaniu, możesz rozważyć podejście, którego używasz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-11 23:10:40
Nie wydaje mi się, że istnieje wymóg, aby klucze z automatycznym numerowaniem były sekwencyjne. W sumie to chyba nie można ich wymagać:
-
Transakcja a rozpoczyna i wstawia
-
Transakcja b rozpoczyna i wstawia
-
Transakcja a przerywa
Masz dziurę. nic na to nie poradzę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Muhan próbuje myśleć o tym w kontekście wielu jednoczesnych połączeń realizujących tę transakcję, a nie pojedynczo. Niektórym się nie uda, a niektórym się uda. Chcesz, aby SQL Server koncentrował się na uruchamianiu nowych żądań w miarę ich napływania, a nie na utrzymywaniu kolumny tożsamości bez luki. IMO to (luki w wartościach) jest zdecydowanie czymś, na co nie warto poświęcać czasu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-11 23:22:39
Nie. Implmentacje sekwencyjne wykorzystują autonomiczną transakcję. W Oracle, autonomiczna transakcja była kiedyś wewnętrzna do dbms, ale teraz jest wystawiona na własny użytek (i jest często używana nieprawidłowo)
PRAGMA AUTONOMOUS_TRANSACTION;'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-11 23:31:09