Blog
Thursday, 10. August 2023

SQL Server Deadlocks

Rainer
IT-Consultant

Das Internet ist voller Dokumentationen zum Thema Deadlocks in Datenbanken. Bei den meisten Beiträgen handelt es sich um Erklärungen dazu, was Deadlocks sind und rudimentäre Informationen zu ihrer Vermeidung. In diesem Zusammenhang wird der schwarze Peter oft den Applikationsentwicklern zugeschoben, denen implizit vorgeworfen wird, sie hätten Statements verwendet, die Sperren an einer Stelle im Code in einer bestimmten Reihenfolge setzen. An einer anderen Stelle verwenden sie aber eine abweichende Reihenfolge, so dass dann eine klassische Deadlock Situation auftritt - nämlich eine Anforderung von Sperren über Kreuz. Hier eine schematische Abbildung dessen:

Mainzer Datenfabrik - SQL Server Deadlocks

Bei vielen der von unseren Kunden beauftragten SQL Server Assessments hat sich eine andere Situation dargestellt, deren Grund in der Datenmodellierung liegt.

In diesem Artikel bauen wir eine derartige Deadlock-Situation auf und zeigen, wie man diese vermeiden kann. Ferner werden wir hier auf einen erfreulichen Nebeneffekt dieser Vermeidungsstrategie, nämlich eine Verbesserung der Performance der Datenbank, eingehen.

Typen von Sperren

Im Rahmen des Handlings von Transaktionen verwendet SQL Server unterschiedliche Sperren, um Daten vor der gleichzeitigen Änderung durch unterschiedliche Sessions zu schützen. Diese Sperren werden in der Microsoft Dokumentation i.d.R. durch Abkürzungen bezeichnet.

Die folgende Tabelle enthält eine Übersicht der wichtigsten Sperren. Details können der Microsoft Dokumentation entnommen werden:

Hinweis zum folgenden Versuchsaufbau

Es gibt viele Beispiele im Internet, die sehr einfach zeigen, wie man einen Deadlock provoziert. In diesem Artikel geht es jedoch darum, zu zeigen, dass das Auftreten von Deadlocks auch durch ungeeignete Datenmodellierung / fehlende Fremdschlüsselindizierung verursacht werden kann.

Versuchsaufbau

Für die verschiedenen hier beschriebenen Szenarien wird eine klassische Master-Detail Beziehung aufgebaut, in der mindestens zwei DB-Sessions gleichzeitig Datensätze ändern. Entsprechend ihrer Bedeutung werden die beiden beteiligten Tabellen mit Masters bzw. Details bezeichnet.

Master- und Detail-Tabelle erhalten hier lediglich eine Spalte für Nutz-/Applikationsdaten mit den Namen mas_data bzw. det_data die jedoch zur Demonstration des Auftretens von Deadlocks irrelevant sind.

Beide Tabellen verwenden eine Spalte für den künstlichen Primärschlüssel (mas_id bzw. det_id) und die Tabelle Detail enthält eine Fremdschlüsselspalte det_mas_id die den Primärschlüssel der Master-Tabelle referenziert. Der Fremdschlüssel der Details-Tabelle enthält die Klausel zum automatischen kaskadierenden Löschen der zugehörigen Detail-Datensätze, wenn Master-Datensätze gelöscht werden. Bis hierher also keine Besonderheit und absoluter Standard. Die beiden folgenden Statements enthalten den entsprechenden SQL Code.

CREATE TABLE [dbo].[Masters](
	[mas_id] [int] IDENTITY(1,1) NOT NULL,
	[mas_data] [varchar](50) NULL,
 CONSTRAINT [PK_Masters] PRIMARY KEY CLUSTERED 
(
	[mas_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Details](
	[det_id] [int] IDENTITY(1,1) NOT NULL,
	[det_mas_id] [int] NOT NULL,
	[det_data] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Details] PRIMARY KEY CLUSTERED 
(
	[det_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Details]  WITH CHECK ADD  CONSTRAINT [FK_Details_Masters] FOREIGN KEY([det_mas_id])
REFERENCES [dbo].[Masters] ([mas_id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Details] CHECK CONSTRAINT [FK_Details_Masters]
GO

Zum Füllen der Tabellen mit einer größeren Anzahl von Datensätzen (100.000 im Fall der Tabelle Masters) werden die folgenden beiden Code-Blöcke verwendet. Die Nutzdaten werden zur Vereinfachung aus dem Wert von NEWID() genommen. Der Fremdschlüssel der Tabelle Details zur Tabelle Masters wird durch einen Zufallswert im Bereich 1 … 100.000 generiert. Die hier verwendete hohe Anzahl von Datensätzen ist für das Erreichen der Deadlock Situation wichtig und kann in Ihrer Umgebung je nach Performance Ihres Servers abweichen.

set nocount on
select current_timestamp
declare @master_records  int = 100000;
declare @aktuell         int = 0;

begin transaction

WHILE @aktuell < @master_records
BEGIN
   insert into masters(mas_data) select CONVERT(nvarchar(50),REPLACE(NEWID(),'-',''));
   SET @aktuell = @aktuell + 1;
END;

commit;
select current_timestamp

Kleiner Hinweis zur Performance: Das Statement zum Füllen der Master-Tabelle hat, wie es hier mit einer einzigen Transaktion verwendet wird, im Mittel 1,15 Sekunden auf einem Laptop benötigt. Wurde die Transaktionsklammer “begin transaction” … “commit;” nicht verwendet und hierdurch für jeden Schleifendurchlauf eine separate Transaktion verwendet, so lag die Laufzeit in etwa beim Zehnfachen (10,15 Sekunden).

Analog wird die Detail-Tabelle gefüllt, wobei der Wert für die Fremdschlüsselspalte über die rand()-Funktion im Bereich 1 … 100.000 gebildet wird. In die Detail Tabelle werden 1.000.000 Datensätze eingefügt, so dass man im Schnitt zehn Detail-Datensätze zu jedem Master-Datensatz erhält.

set nocount on
select current_timestamp
declare @detail_records        int = 1000000;
declare @mas_key_multiplicator int = @detail_records / 10;
declare @aktuell               int = 0;

begin transaction

WHILE @aktuell < @detail_records
begin
   insert into details(det_mas_id, det_data) values( floor( rand() * 100000 + 1), CONVERT(nvarchar(50),REPLACE(NEWID(),'-','')));
   set @aktuell = @aktuell + 1;
END

commit;
select current_timestamp

Fehlt hier nicht noch etwas?
Der erfahrene DBA wird in der o.a. Konstruktion sicherlich bemerkt haben, dass die hier dargestellte Situation verbesserungswürdig ist, dass nämlich der Fremdschlüssel der Tabelle DETAILS auf die Tabelle MASTERS nicht indiziert ist. Das ist aber beabsichtigt und Teil der hier durchgeführten Untersuchungen, weil wir diese Situation bei mehreren Kunden im Rahmen unserer SQL Server Assessments vorgefunden haben.

Auch hier ein Hinweis zur Laufzeit: Das Einfügen der 1.000.000 hat in der Testumgebung durchschnittlich 15,34 Sekunden benötigt.

Erzeugen der Deadlock-Situation

Um einen Deadlock in der o.a. Datenbank zu erzeugen, wird eine Session (A) zur Datenbank aufgebaut und mit dem u.a. Statement eine Transaktion zum Löschen eines Master-Datensatzes gestartet. Die Transaktion wird noch nicht abgeschlossen, so dass die beteiligten Tabellen MASTERS UND DETAILS (durch das kaskadierende Löschen) für andere Transaktionen gesperrt sind.

Anschließend werden zwei weitere Sessions (B und C) parallel zu A aufgebaut. Diese versuchen, einen Detail- bzw. einen Master-Datensatz zu löschen.

In diesem Szenario können natürlich beliebige vorhandene Datensätze gelöscht werden. Hier wurden als Werte für mas_id bzw. det_mas_id die IDs der entsprechenden Sessions verwendet.

/*
**  Session A, Session-ID 71
*/
begin tran
delete from masters where mas_id = 71

/*
**  Session B, Session-ID 72
*/
begin tran
delete from details where det_mas_id = 72

/*
**  Session C, Session-ID 73
*/
begin tran
delete from masters where mas_id = 73

Im nächsten Schritt wird in der Session A, die zuerst gestartet wurde und die bereits die delete-Operationen durchgeführt (aber noch nicht per commit abgeschlossen) hat ein Rollback durchgeführt. Hierdurch werden in der Datenbank die Sperren auf Masters und Details aufgehoben, so dass die anderen beiden Transaktionen B und C gleichzeitig starten. Nach einer kurzen Wartezeit (max. ca. fünf Sekunden) sehen wir in einigen Fällen, je nach DB-internem Bearbeiten der erforderlichen Sperren, dass die eine Session (B oder C) erfolgreich durchlief während die andere (C bzw. B) wegen einer entstandenen Deadlock-Situation von der Datenbank abgebrochen wurde.

Fehlermeldung:

Meldung 1205, Ebene 13, Status 52, Zeile 2
Die Transaktion (Prozess-ID 73) befand sich auf Sperre Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus.

Zum Abschluss dieses Tests wird jetzt in der Session, die keinen Abbruch erfahren hat (B oder C) ein Rollback durchgeführt, so dass er ggf. mit unveränderten Daten erneut ausgeführt werden kann.

Wie bereits erwähnt, ist das Auftreten des Deadlocks in diesem Testaufbau abhängig vom DB-internen Timing bei der der Vergabe der Sperren und die Wahrscheinlichkeit steigt mit der Anzahl der Datensätze in der Details-Tabelle.

Wie kann dieser Deadlock nun verhindert werden?

Das Problem bei diesem Versuchsaufbau ist die von SQL Server benötigte restriktive Sperre der beteiligten Resourcen:

Sehen wir uns dazu zunächst die Sperren kurz vor dem Rollback von Session A an. Hierzu wird das folgende Statement verwendet, das i.W. aus der Stored Procedure sp_lock() der Master-Datenbank stammt, aber leicht erweitert wurde:

select 	convert (smallint, req_spid) As [Session-ID],
		i.name as [Objekt-/Indexname],
  		o.type_desc as [Objekttyp],
		v.name As [Lock-Ebene],
		u.name As [Lock-Mode],
		x.name As Status
	from 	master.dbo.syslockinfo,
		master.dbo.spt_values v,
		master.dbo.spt_values x,
		master.dbo.spt_values u,
		sys.objects o,
		sys.indexes i
	where   master.dbo.syslockinfo.rsc_type = v.number
			and v.type = 'LR'
			and master.dbo.syslockinfo.req_status = x.number
			and x.type = 'LS'
			and master.dbo.syslockinfo.req_mode + 1 = u.number
			and u.type = 'L'
			and rsc_objid = o.object_id
			and o.object_id = i.object_id
	order by o.name desc
               , u.name desc

In einer ruhenden Datenbank mit nur einer laufenden Abfrage (für das o.a. Statement in Session 71) liefert dieses Statement die folgenden beiden Zeilen:

Mainzer Datenfabrik - SQL Server Deadlocks

Nachdem alle drei Transaktionen gestartet wurden, ergibt sich das u.a. Bild bezüglich der Sperren:

Transaktion A mit der Session-ID 71 belegt eine exklusive (“X”) Sperre auf einer einzelnen Zeile (“KEY”) der Tabelle MASTERS. Um diese Sperre setzen zu können, muss zunächst auf übergeordneter Ebene gesperrt werden. Es wird hier zunächst eine XI-Sperre auf Tabellen-Ebene (TAB, Zeile 4) und dann auf Seitenebene (PAG, Zeile 5) gesetzt. Diesen XI-Sperren folgt dann die exklusive Sperre auf Zeilen-Ebene (KEY, Zeile 3). Alle diese Sperren wurden Transaktion A bereits erteilt (“GRANT”). Bezüglich der Details Tabelle sieht die Situation folgendermaßen aus:

  • Zum Löschen des Master-Datensatzes muss die gesamte DETAILS Tabelle exklusiv gesperrt (Zeile 6, TAB, X, GRANT) werden

  • Transaktionen B und C mit der Session-Nr. 72 bzw. 73 kündigen eine exklusive Sperre auf der DETAILS Tabelle an, müssen aber auf die Freigabe der exklusiven Sperre der Transaktion A warten (Zeilen 7 und 8, TAB, IX, WAIT)

Mainzer Datenfabrik - SQL Server Deadlocks

Führt man anschließend das Rollback-Kommando in Session A zusammen mit dem o.a. SQL Fragment aus sp_lock() zur Ermittlung der Sperren aus, so bietet sich folgendes Bild, das einen kurzzeitigen Snapshot während des Setzens der erforderlichen Sperren darstellt:

  • Das Ergebnis enthält über 10.000 Zeilen
  • Die Sperren der Transaktion A bezüglich der Objekte PK_Masters bzw. PK_DETAILS sind aufgehoben und es existieren nur noch die zwei Zeilen die sich auf die System-Objekte clst und nc beziehen.
  • Es existieren neun exklusive Sperren durch Session 72 auf Zeilenebene (Ausschnitt 1)
  • Session 72 hat 12 weitere Sperren des Typs “UIX” auf Tabellenebene (Ausschnitt 2)
  • Session 72 hat 14 weitere Sperren des Type “U” = “Update” (Ausschnitte 3 Grant bzw. 3 Wait).
  • Session 73 hat 10 IX-Sperren auf Tabellen-Ebene (Ausschnitt 4)
  • Session 73 hat 10.663 U-Sperren auf Seitenebene (Ausschnitt 5, Teilansicht). Eine dieser Sperren hat den WAIT-Status

Da es sich hier um einen Snapshot handelt, können die o.a. Mengenbetrachtungen je nach instanz-internem Timing stark voneinander abweichen. Bei zwei weiteren Versuchsdurchläufen existierten unmittelbar nach dem Rollback ca. 12.000 bzw. ca. 43.000 Sperren Sperren der Menge { “IX”, “U”, “UIX”, “X”) in unterschiedlicher Verteilung.

Mainzer Datenfabrik - SQL Server Deadlocks
Mainzer Datenfabrik - SQL Server Deadlocks
Mainzer Datenfabrik - SQL Server Deadlocks
Mainzer Datenfabrik - SQL Server Deadlocks
Mainzer Datenfabrik - SQL Server Deadlocks
Mainzer Datenfabrik - SQL Server Deadlocks

Als Deadlock auslösende Ursache haben wir hier die Anforderung, dass Session 72 zur Ermittlung der Löschkandidaten einen vollständigen Scan des Clustered Index PK_Details bei einer großen Anzahl von Datensätzen durchführen muss, es müssen also alle 1.000.000 Datensätze bzgl. des Kriteriums “det_mas_id = 72” durchsucht und die benötigten Sperren gesetzt werden. Session 73 muss beim Löschen des Master-Datensatzes auch die zugehörigen Detail-Datensätze löschen und hierzu einen vollständigen Scan des Clustered Index PK_Details mit dem Kriterium “det_mas_id = 73” durchführen und entsprechend sperren. Offensichtlich ist es hierbei dann zu der Anfangs graphisch dargestellten Überkreuzanforderung von Datenbanksperren gekommen.

Bitte in diesem Zusammenhang beachten:

  1. Bei kleiner Anzahl von Datensätzen in der DETAILS Tabelle konnte der Deadlock nicht provoziert werden
  2. Mit wachsender Anzahl von Datensätzen in der DETAILS Tabelle häufte sich das Auftreten des Deadlock

Damit hätten wir eine klassische Situation:

  • Der Entwickler / Softwarehersteller kann mit seinem relativ geringen Datenumfang keine Deadlocks feststellen
  • Beim Kunden macht die Datenbank zu Beginn keine Probleme
  • Mit wachsendem Datenumfang häufen sich die Deadlocks (i.d.R. für den Benutzer transparent) und führen zu einem Performanceverlust.

Indizierung des Fremdschlüssels

Im nächsten Versuch wird die Fremdschlüsselspalte der Tabelle DETAILS (det_mas_id) mit dem folgenden Statement indiziert:

CREATE NONCLUSTERED INDEX [NCI-FK_DET_MAS] ON [dbo].[Details]
(
	[det_mas_id] ASC
)WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF
      , DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON
	  , ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO

Beginnt man mit der ersten Transaktion in Session 71 und fährt mit den Sessions 72 und 73 fort, wieder ohne die Transaktionen mit Commit zu beenden, so bemerkt man, dass trotz der noch offenen Transaktion in Session 71 keine Wartezustände für die Sessions 72 und 73 auftreten. Keine der drei Sessions behindert also in irgendeiner Weise die anderen beiden und wird von keiner der anderen beiden behindert. Dies wurde dadurch erreicht, dass die Löschkandidaten jetzt über den Index NCI_FK_DET_MAS ohne aufwändige Scans gezielt adressiert, gesperrt und gelöscht werden können.

Die in diesem Versuch benötigen exklusiven Sperren sind erheblich weniger restriktiv als in der Ausgangssituation und liegen ausnahmslos auf Zeilenebene (“KEY”, “X”, “GRANT”), während in der Ausgangssituation die komplette Tabelle DETAILS sowohl zum Löschen von Master- als auch von Detail-Datensätzen exklusiv gesperrt werden musste.

Laufzeitversuche

Abgesehen von der Eliminierung von Deadlocks bringt der Fremdschlüsselindex zusätzlich eine erhebliche Performancesteigerung, da dieser ja die vollständigen Scans der relativ umfangreichen Detail-Tabelle vermeidet. In diesem Kapitel wird die Laufzeit für folgenden Fälle untersucht:

  1. Die Spalte det_mas_id ist nicht indiziert, der Fremdschlüssel der Tabelle Details auf die Tabelle Masters ist kaskadierend eingerichtet
  2. Die Spalte det_mas_id ist nicht indiziert, der Fremdschlüssel der Tabelle Details auf die Tabelle Masters ist nicht kaskadierend eingerichtet, so dass beim Löschen zunächst alle Detail-Datensätze und anschließend der zugehörige Master-Datensatz gelöscht werden muss
  3. Die Spalte det_mas_id ist indiziert, der Fremdschlüssel der Tabelle Details auf die Tabelle Masters ist kaskadierend eingerichtet
  4. Die Spalte det_mas_id ist indiziert, der Fremdschlüssel der Tabelle Details auf die Tabelle Masters ist nicht kaskadierend eingerichtet

Für die o.a. Test-Szenarien wurden fünf Master-Datensätze als Löschkandidaten verwendet. Für jeden Test wurden fünf Läufe durchgeführt. Jede Löschtransaktion wurde per Rollback zurückgenommen. Die folgenden beiden Codeblöcke verwendet:

/*
  Testreihe zum kaskadierenden Löschen von Datensätzen der
  Tabelle MASTERS.
  In jedem Durchlauf werden fünf Datensätze gelöscht.
  Die Löschung werden per Rollback wieder zurückgenommen:
*/

select current_timestamp

declare @SQL nvarchar(500);
declare @loop_count int = 0;

set @SQL = 'delete from masters where mas_id in('
while @loop_count < 5
begin
   set @SQL = @SQL + cast( floor( rand() * 100000 + 1) as nvarchar) + ','
   set @loop_count = @loop_count + 1
end
set @SQL = @SQL + ')'
set @SQL = replace(@SQL, ',)',')')

begin tran
exec (@SQL)
rollback

select current_timestamp
/*
  Testreihe zum nicht-kaskadierenden Löschen von Datensätzen der
  Tabelle MASTERS.
  Im ersten Teil werden die Detail-Datensätze zu fünf Löschkandidaten 
  entfernt, anschließend die fünf Master-Datensätze. 
  Die Löschungen werden per Rollback wieder zurückgenommen:
*/
select current_timestamp

declare @SQL_Masters nvarchar(500);
declare @SQL_Details nvarchar(500);
declare @loop_count int = 0;

set @SQL_Details = 'delete from details where det_mas_id in('
while @loop_count < 5
begin
   set @SQL_Details = @SQL_Details + cast( floor( rand() * 100000 + 1) as nvarchar) + ','
   set @loop_count = @loop_count + 1
end
set @SQL_Details = @SQL_Details + ')'
set @SQL_Details = replace(@SQL_Details, ',)',')')
set @SQL_Masters = replace( replace( @SQL_DETAILS, 'details','masters' ), 'det_mas', 'mas')


begin tran
exec (@SQL_Details)
exec (@SQL_Masters)
rollback

select current_timestamp

Ergebnis der Messungen

Die folgende Tabelle gibt die Ergebnisse der vier Testreihen wieder. Alle Werte sind in Sekunden angegeben.

Massentests

In einer weiteren Testreihe wurden die gleichen Einstellungen und Datensätze wie oben verwendet, wobei die Datenbank einem Stresstest unterzogen wurde. Hierzu wurde das von Microsoft herausgegebene RML-Tool verwendet. Dieses Tool ist auch unter dem Namen ostress bekannt und es lässt sich über Replay Markup Language Utilities - SQL Server herunterladen und installieren.

Das Tool wurde mit 100 parallelen Sessions, 100 Aufrufen und einem der o.a. Löschstatements für kaskadierendes bzw. nicht kaskadierendes Löschen aufgerufen. Aus den hundert resultierenden Session-Protokolldateien wurden stichprobenartig fünf Dateien mit jeweils 100 Ausführungszeiten ausgewählt, um das entsprechende Timing in der folgenden Tabelle wiederzugeben:

Testfall 2 ist ohne Ergebnis, weil die in diesem Fall von der Instanz verwendeten Sperren auf Seitenebene (“PAG”, “UIX”) statt auf Zeilenebene liegen. Hierdurch und durch die starke Parallelisierung trat vermutlich die zu Beginn dieses Artikels graphisch dargestellte Situation auf. Hier sind im Schnitt ca. 99 % der 100 Transaktionen auf Grund von Deadlocks abgebrochen worden und es trat der unter MSSQLSERVER_1204 - SQL Server dokumentierte Fehler 1204 auf.

Eine quantitative Darstellung der jeweiligen Sperrsituationen für eine einzelne Session ist in den folgenden Unterkapiteln dargestellt. Hinweis hierzu: Die Zahlen können bei Ihren Versuchen leicht abweichen, weil es bei Ihnen eine statistisch abweichende Verteilung der Detail-Datensätze zu den Master-Datensätzen geben wird.

Quantitative Darstellung der Sperren, nicht indiziert, kaskadierend

Die Sperre der Detail-Datensätze betrifft die gesamte DETAILS-Tabelle, was zu der hohen Laufzeit des ersten Testfalls führt.

Mainzer Datenfabrik - SQL Server Deadlocks

Quantitative Darstellung der Sperren, nicht indiziert, nicht kaskadierend

Die exklusiven Sperren (“UIX”) der DETAILS-Tabelle betreffen zwar “nur” 46 Objekte, aber da es sich hier um Sperren auf Seitenebene handelt, sind hiervon sehr viele Zeilen betroffen. Die starke Parallelisierung hat hier vermutlich zu der eingangs graphisch dargestellten Situation geführt.

Mainzer Datenfabrik - SQL Server Deadlocks

Quantitative Darstellung der Sperren, indiziert, kaskadierend

Exklusive Sperren der DETAILS-Tabelle betreffen nur einzelne Zeilen oder zusammenliegende Bereiche einzelner Zeilen. Sowohl der Clustered Index (PK_Details), als auch der Non-Clustered Index auf der Fremdschlüsselspalte (NCI-FK_DET_MAS) sind hiervon betroffen.

Mainzer Datenfabrik - SQL Server Deadlocks

Quantitative Darstellung der Sperren, indiziert, nicht kaskadierend

Auch hier betreffen die verwendeten Sperren lediglich einzelne Zeilen.

Mainzer Datenfabrik - SQL Server Deadlocks

Fazit

Die Schuld für ein erhöhtes Deadlock-Aufkommen muss nicht zwingend beim Entwickler, sondern kann auch, wie hier gezeigt, bei der Datenmodellierung liegen. Wichtig ist es, Fremdschlüssel zu indizieren, was nicht nur Deadlocks reduziert bzw. vermeidet, sondern auch den netten Nebeneffekt einer deutlichen Performancesteigerung der Datenbank hat. Dies hat sich insbesondere bei dem Massentest mit 100 parallelen Sessions gezeigt: Hier hatte die Datenbank in den Testfällen 3 und 4 keine wesentlichen Performanceeinbußen gegenüber den Tests mit einer einzelnen Session. Unser Laptop hat die hohe Last ohne merkbare Performanceeinbußen verkraftet.

Wenn Sie mehr über das Thema Deadlocks erfahren möchten, stehen Ihnen unsere Expert:innen gerne in einem unverbindlichen Beratungsgespräch zur Verfügung. Kontaktieren Sie uns dafür ganz einfach über unserKontaktformular! Wir freuen uns von Ihnen zu hören.

Interesse geweckt?

Unsere Expert:innen stehen Ihnen bei allen Fragen rund um Ihre IT Infrastruktur zur Seite.

Kontaktieren Sie uns gerne über das Kontaktformular und vereinbaren ein unverbindliches Beratungsgespräch mit unseren Berater:innen zur Bedarfsevaluierung. Gemeinsam optimieren wir Ihre Umgebung und steigern Ihre Performance!
Wir freuen uns auf Ihre Kontaktaufnahme!

Taunusstraße 72
55118 Mainz
info@madafa.de
+49 6131 3331612
Bürozeiten
Montag bis Donnerstag:
9:00 - 17:00 Uhr MEZ

Freitags:
9:30 - 14:00 Uhr MEZ
Wir sind Ihre SQL Expert:innen!
Noch Fragen? - Wir haben immer die passende Antwort für Sie!