Deadlock (zakleszczenie) w SQL Server to sytuacja, w której dwie lub więcej transakcji wzajemnie się blokują — każda czeka na zasób zablokowany przez drugą, tworząc cykliczną zależność. SQL Server automatycznie wykrywa deadlocki (monitor sprawdza co 5 sekund, a przy ich wykryciu nawet co 100 ms) i rozwiązuje je, wybierając jedną z transakcji jako ofiarę (victim) — kończy ją błędem 1205, co pozwala drugiej transakcji kontynuować pracę.
W skrócie
- Deadlock to nie blokowanie (blocking) — blokowanie mija, gdy właściciel zwolni zasób; deadlock trwałby w nieskończoność, gdyby nie interwencja monitora
- SQL Server automatycznie kończy deadlock błędem 1205 — aplikacja musi go obsłużyć i ponowić transakcję
- Główne narzędzie diagnostyczne w 2026: system_health Extended Event (domyślnie włączony) — przechowuje pełne raporty deadlocków w XML
- W SQL Server 2022/2025 wprowadzono Optimized Locking — zmniejsza ryzyko deadlocków przez wcześniejsze zwalnianie blokad wierszy i stron
- Kluczowa profilaktyka: READ_COMMITTED_SNAPSHOT ON, krótkie transakcje, dostęp do obiektów w tej samej kolejności
Czym dokładnie jest deadlock w SQL Server
Deadlock (nazywany też deadly embrace — śmiertelnym uściskiem) to szczególny przypadek blokowania, w którym żadna z transakcji nie może postąpić naprzód. W przeciwieństwie do zwykłego blokowania (gdzie transakcja A czeka na B, ale B nie czeka na A — więc B w końcu się zakończy i zwolni zasób), w deadlocku A czeka na B i jednocześnie B czeka na A.
Prosty mechanizm — przykład
- Transakcja A zakłada blokadę współdzieloną (S) na wierszu 1.
- Transakcja B zakłada blokadę współdzieloną (S) na wierszu 2.
- Transakcja A żąda blokady wyłącznej (X) na wierszu 2 — czeka na zwolnienie blokady przez B.
- Transakcja B żąda blokady wyłącznej (X) na wierszu 1 — czeka na zwolnienie blokady przez A.
W tym momencie obie transakcje czekają na siebie nawzajem. Bez interwencji zewnętrznego mechanizmu czekałyby w nieskończoność.
Rodzaje zasobów, które mogą powodować deadlocki
Deadlocki w SQL Server nie ograniczają się tylko do blokad na danych. Monitor deadlocków sprawdza następujące typy zasobów:
| Typ zasobu | Opis | Przykład |
|---|---|---|
| Locks | Blokady na obiektach, stronach, wierszach, metadanych | Najczęstszy typ — rywalizacja o te same dane |
| Worker threads | Wątki robocze | Sesja trzymająca blokadę nie może pobrać wątku, by zwolnić blokadę |
| Memory | Przydziały pamięci dla zapytań | Dwa zapytania czekające na siebie przy ograniczonej pamięci |
| Parallel query resources | Zasoby zapytań równoległych | Wątki koordynatora/producenta/konsumenta blokujące się wzajemnie |
| MARS resources | Kontrola przeplotu zapytań w MARS | Dwa żądania w tej samej sesji czekające na siebie |
| Session/Transaction mutex | Wyłączność sesji i transakcji | Procedura składowana blokuje mutex sesji, a drugie żądanie czeka |
Jak zdiagnozować deadlock — narzędzia w 2026 roku
1. system_health Extended Event (rekomendowane) ⭐
Od SQL Server 2012 domyślnie uruchomiona jest sesja zdarzeń rozszerzonych system_health, która automatycznie przechwytuje zdarzenia xml_deadlock_report. To podstawowe i zalecane narzędzie diagnostyczne — nie wymaga żadnej konfiguracji.
Raport deadlocka w XML zawiera trzy główne węzły:
- victim-list — identyfikator procesu wybranego na ofiarę
- process-list — szczegóły wszystkich procesów: SPID, zapytanie (inputbuf), stos wywołań (executionStack), czas oczekiwania, poziom izolacji, nazwa hosta, login
- resource-list — zasoby biorące udział w deadlocku: KEY, RID, PAGE, OBJECT z identyfikatorami bazy, obiektu, indeksu
Jak odczytać raport — zapytanie T-SQL:
SELECT
xdr.value('@timestamp', 'datetime') AS deadlock_time,
xdr.query('.') AS event_data
FROM (
SELECT CAST(target_data AS XML) AS target_data
FROM sys.dm_xe_session_targets AS xt
INNER JOIN sys.dm_xe_sessions AS xs
ON xs.address = xt.event_session_address
WHERE xs.name = N'system_health'
AND xt.target_name = N'ring_buffer'
) AS XML_Data
CROSS APPLY target_data.nodes(
'RingBufferTarget/event[@name="xml_deadlock_report"]'
) AS XEventData(xdr)
ORDER BY deadlock_time DESC;
W SSMS kliknij komórkę z danymi XML — otworzy się graficzny wykres deadlocka (procesy, zasoby, strzałki wskazujące zależności). Możesz też zapisać XML jako plik .xdl i otworzyć go ponownie w SSMS, by uzyskać wizualizację.
2. Trace flag 1204 i 1222 (legacy — unikać na produkcji)
Trace flag 1204 i 1222 zapisują szczegóły deadlocków w SQL Server error log. TF 1204 formatuje dane węzłami, TF 1222 — najpierw procesami, potem zasobami (w formacie XML-podobnym). Można włączyć oba jednocześnie.
⚠ Uwaga: Microsoft odradza używanie trace flag 1204/1222 na obciążonych systemach produkcyjnych — mogą powodować problemy wydajnościowe. Zawsze preferuj Extended Events.
3. SQL Profiler — Deadlock Graph (przestarzałe)
SQL Profiler i SQL Trace zostały oficjalnie wycofane (deprecated). Zastąp je Extended Events, które mają mniejszy narzut wydajnościowy i są bardziej konfigurowalne.
Porównanie narzędzi diagnostycznych
| Narzędzie | Zalecane w 2026? | Narzut wydajnościowy | Domyślnie włączone | Graficzna wizualizacja |
|---|---|---|---|---|
| system_health XEvent | ✅ Tak — podstawowe | Minimalny | ✅ Tak | ✅ Tak (przez SSMS) |
| TF 1204 | ❌ Legacy | Znaczący przy dużym obciążeniu | ❌ Nie | ❌ Nie |
| TF 1222 | ❌ Legacy | Znaczący przy dużym obciążeniu | ❌ Nie | ❌ Nie |
| SQL Profiler | ❌ Przestarzałe | Wysoki | ❌ Nie | ✅ Tak (wykres) |
Jak naprawić i zapobiegać deadlockom
Obsługa błędu 1205 w aplikacji
Każda aplikacja komunikująca się z SQL Server musi mieć handler błędu 1205. Bez niego aplikacja będzie kontynuować pracę, nieświadoma, że jej transakcja została wycofana.
Wzorzec obsługi w T-SQL z użyciem TRY...CATCH:
DECLARE @retry INT = 0;
WHILE @retry < 3
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
-- operacje na danych
COMMIT;
BREAK;
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 1205
BEGIN
ROLLBACK;
SET @retry = @retry + 1;
WAITFOR DELAY '00:00:01'; -- losowe opóźnienie 1-3 s
END;
ELSE THROW;
END CATCH;
END;
Kluczowe: losowe opóźnienie przed ponowieniem (1–3 sekundy) zmniejsza prawdopodobieństwo, że deadlock wystąpi ponownie — daje drugiej transakcji czas na zakończenie.
8 sprawdzonych technik zapobiegania deadlockom
1. Dostęp do obiektów w tej samej kolejności
Jeśli wszystkie transakcje pobierają blokady na tabelach A, potem B, potem C — zawsze w tej samej kolejności — cykl zależności nie powstanie. Używanie procedur składowanych do wszystkich modyfikacji danych pomaga ustandaryzować tę kolejność.
2. Krótkie transakcje, jeden batch
Im dłużej trwa transakcja, tym dłużej utrzymywane są blokady wyłączne (X) i aktualizacji (U). Wykonuj całą transakcję w jednym batchu — unikaj round-tripów sieciowych wewnątrz transakcji.
3. Unikaj interakcji z użytkownikiem wewnątrz transakcji
Nigdy nie czekaj na input użytkownika, gdy transakcja jest otwarta. Blokady są zwalniane dopiero po COMMIT lub ROLLBACK — w tym czasie inne transakcje stoją w kolejce.
4. READ_COMMITTED_SNAPSHOT ON (RCSI) ⭐
Najważniejsza rekomendacja Microsoftu dla wszystkich aplikacji:
ALTER DATABASE TwojaBaza SET READ_COMMITTED_SNAPSHOT ON;
Po włączeniu tej opcji transakcje w izolacji READ COMMITTED używają wersjonowania wierszy zamiast blokad współdzielonych podczas odczytów. Oznacza to, że SELECT nie blokuje UPDATE i odwrotnie — eliminuje to najczęstszą przyczynę deadlocków między odczytem a zapisem.
5. Snapshot Isolation
Krok dalej niż RCSI — wymaga ustawienia ALLOW_SNAPSHOT_ISOLATION ON i jawnego użycia SET TRANSACTION ISOLATION LEVEL SNAPSHOT. Zapewnia spójny widok danych na początek transakcji bez żadnych blokad.
6. Unikaj wyższych poziomów izolacji
REPEATABLE READ i SERIALIZABLE utrzymują blokady współdzielone do końca transakcji, drastycznie zwiększając ryzyko deadlocków. Używaj tylko wtedy, gdy jest to absolutnie konieczne.
7. SET DEADLOCK_PRIORITY
Możesz nadać sesji priorytet w sytuacji deadlocka:
SET DEADLOCK_PRIORITY LOW; -- ta sesja będzie ofiarą
SET DEADLOCK_PRIORITY HIGH; -- ta sesja przetrwa
Skala: od -10 do 10 (domyślnie NORMAL = 0). Sesja z niższym priorytetem zostanie wybrana na ofiarę. Przy równym priorytecie — SQL Server wybiera transakcję najtańszą do wycofania.
8. Optimized Locking (SQL Server 2022/2025)
Nowy mechanizm dostępny w SQL Server 2022 i udoskonalony w wersji 2025. Przy włączonym Optimized Locking blokady wierszy i stron nie są utrzymywane do końca transakcji — są zwalniane natychmiast po zaktualizowaniu wiersza. Dodatkowo, gdy RCSI jest włączone, blokady aktualizacji (U) w ogóle nie są używane. Efekt: znacząco mniej deadlocków, szczególnie przy dużym współbieżnym obciążeniu.
Najczęstsze problemy przy diagnostyce
Nie mogę znaleźć raportu deadlocka w system_health
Ring buffer system_health ma ograniczoną pojemność (domyślnie 4 MB dla każdego targetu). Przy dużej liczbie zdarzeń starsze wpisy są nadpisywane. Rozwiązanie: utwórz dedykowaną sesję Extended Events z targetem event_file:
CREATE EVENT SESSION [DeadlockMonitor] ON SERVER
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file(SET filename = N'C:\Temp\Deadlocks.xel')
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY = 5 SECONDS);
ALTER EVENT SESSION [DeadlockMonitor] ON SERVER STATE = START;
Deadlocki występują, ale raport nie pokazuje się w system_health
Sprawdź, czy sesja system_health jest uruchomiona:
SELECT name, status_desc FROM sys.dm_xe_sessions WHERE name = 'system_health';
Jeśli status to STOPPED, uruchom ją: ALTER EVENT SESSION system_health ON SERVER STATE = START;
Myli mi się deadlock ze zwykłym blokowaniem (blocking)
Kluczowa różnica: w blokowaniu jest tylko jedna strona czekająca — właściciel zasobu nie czeka na nic od blokowanego. W deadlocku obie strony czekają na siebie. Do diagnostyki blokowania użyj sp_who2, sys.dm_exec_requests z blocking_session_id lub sp_BlitzLock (Brent Ozar).
Częste pytania
Czym różni się deadlock od zwykłego blokowania (blocking)?
W blokowaniu transakcja A czeka na zasób trzymany przez B, ale B nie czeka na A — B w końcu się zakończy i zwolni zasób. Deadlock to cykliczne blokowanie: A czeka na B i B czeka na A. SQL Server rozwiązuje deadlock automatycznie (błąd 1205), natomiast blokowanie może trwać dowolnie długo, dopóki właściciel nie zwolni zasobu.
Czy deadlock w SQL Server oznacza uszkodzenie danych?
Nie. SQL Server wycofuje (ROLLBACK) transakcję-ofiarę, przywracając dane do stanu sprzed jej rozpoczęcia. Żadne dane nie są tracone — aplikacja otrzymuje błąd 1205 i powinna ponowić transakcję. Integralność bazy pozostaje nienaruszona.
Jak sprawdzić, czy w mojej bazie występują deadlocki, bez dostępu do SSMS?
Uruchom zapytanie odczytujące ring buffer system_health (podane wyżej w sekcji diagnostycznej) — działa przez każde narzędzie obsługujące T-SQL: Azure Data Studio, sqlcmd, PowerShell (Invoke-SqlCmd). Alternatywnie, monitoruj licznik PerfMon SQLServer:Locks > Number of Deadlocks/sec.
Czy włączenie READ_COMMITTED_SNAPSHOT ma jakieś wady?
Główna wada to zwiększone zużycie tempdb — SQL Server przechowuje wersje wierszy w tempdb, co przy intensywnych modyfikacjach może obciążyć ten magazyn. Dodatkowo aplikacje polegające na blokującym zachowaniu READ COMMITTED (np. oczekujące na zakończenie innej transakcji przed odczytem) mogą wymagać dostosowania logiki.
Czy Optimized Locking całkowicie eliminuje deadlocki?
Nie. Optimized Locking znacząco redukuje ryzyko deadlocków, ale nie eliminuje ich całkowicie — deadlocki wciąż mogą wystąpić na zasobach takich jak wątki robocze, pamięć czy rywalizacja o Transaction ID (TID). Mechanizm jest jednak najskuteczniejszą dotychczasową optymalizacją Microsoftu w tym obszarze.
Jak sprawdzić, które zapytania najczęściej uczestniczą w deadlockach?
Odczytaj raporty z system_health, wyodrębnij pole inputbuf z każdego procesu i pogrupuj. Możesz też użyć narzędzia sp_BlitzLock z First Responder Kit Brent Ozara, które parsuje system_health i przedstawia zagregowane statystyki — które zapytania, tabele i indeksy pojawiają się najczęściej.
Czy mogę całkowicie pozbyć się deadlocków?
Nie da się ich w 100% wyeliminować w systemie ze współbieżnymi transakcjami — to nieodłączna cecha każdej relacyjnej bazy danych z blokadami. Można jednak zredukować ich częstotliwość do poziomu marginalnego, stosując RCSI, Optimized Locking, krótkie transakcje i ustandaryzowaną kolejność dostępu do obiektów.
Wydajny SQL Server potrzebuje solidnej licencji
Niezależnie od tego, czy stawiasz nowy serwer, migrujesz na SQL Server 2022/2025, czy optymalizujesz istniejącą instancję pod kątem deadlocków — podstawa to legalne i w pełni wspierane środowisko. W KluczeSoft znajdziesz oryginalne licencje Microsoft SQL Server w cenach nawet 70% niższych od sugerowanych — w pełni zgodne z prawem Unii Europejskiej (wyrok TSUE UsedSoft, C-128/11).
→ Licencje Microsoft SQL Server i Windows Server — sprawdź dostępne edycje
Artykuł opracowano na podstawie oficjalnej dokumentacji Microsoft Learn (Deadlocks Guide, stan na maj 2026), testów w SQL Server 2022/2025 oraz narzędzi społeczności DBATools i First Responder Kit. KluczeSoft jest niezależnym sprzedawcą — nie jest powiązany z Microsoft Corporation.
<!-- IL-V1 -->Powiązane artykuły
- Jak naprawić instalację Office 2024 — kompletny poradnik krok po kroku — Jeśli Microsoft Office 2024 przestał działać poprawnie — nie uruchamia się, zawiesza, wyświetla błędy aktywacji lub brakuje niektórych funkc.
- SQL Server tempdb — konfiguracja i najlepsze praktyki (2026) — Tempdb to baza systemowa obecna w każdej instancji SQL Servera, odtwarzana od nowa przy każdym restarcie serwera.
- Błąd instalacji Microsoft 365 — jak naprawić krok po kroku (2026) — Poniższa tabela zbiera najczęściej występujące kody błędów wraz z ich znaczeniem i zalecanym działaniem — zapisz ją, bo gdy pojawi się błąd.
- Group Policy w Windows Server 2025 — najlepsze praktyki konfiguracji i zarządzania w 2026 roku — Group Policy to mechanizm systemu Windows Server pozwalający administratorom domeny na centralne definiowanie i wymuszanie ustawień systemow.
- Jak naprawić instalację Office 2021 — skuteczne metody krok po kroku — Jeśli Microsoft Office 2021 przestał działać poprawnie — Word się zawiesza, Excel nie otwiera plików, a Outlook odmawia posłuszeństwa — nie.
