{"meta":{"title":"Beheben von Datenbankdeadlocks oder Datenintegritätsproblemen","intro":"Copilot Chat kann Ihnen dabei helfen, Code zu vermeiden, der zu langsamen oder blockierten Datenbankvorgängen oder Tabellen mit fehlenden oder falschen Daten führt.","product":"GitHub Copilot","breadcrumbs":[{"href":"/de/copilot","title":"GitHub Copilot"},{"href":"/de/copilot/tutorials","title":"Anleitungen"},{"href":"/de/copilot/tutorials/copilot-cookbook","title":"GitHub Copilot Kochbuch"},{"href":"/de/copilot/tutorials/copilot-cookbook/refactor-code","title":"Umgestalten von Code"},{"href":"/de/copilot/tutorials/copilot-cookbook/refactor-code/fix-database-deadlocks","title":"Beheben von Datenbankdeadlocks"}],"documentType":"article"},"body":"# Beheben von Datenbankdeadlocks oder Datenintegritätsproblemen\n\nCopilot Chat kann Ihnen dabei helfen, Code zu vermeiden, der zu langsamen oder blockierten Datenbankvorgängen oder Tabellen mit fehlenden oder falschen Daten führt.\n\nKomplexe Datenbankvorgänge – insbesondere solche, die Transaktionen betreffen – können zu Deadlocks oder Dateninkonsistenzen führen, die schwer zu debuggen sind.\n\nCopilot Chat kann helfen, indem es Stellen innerhalb einer Transaktion identifiziert, an denen Sperren oder Deadlocks auftreten könnten, und bewährte Methoden für die Transaktionsisolation oder die Auflösung von Deadlocks empfiehlt, z. B. durch Anpassung von Sperrstrategien oder durch eine saubere Behandlung von Deadlock-Ausnahmen.\n\n> \\[!NOTE] Bei den in diesem Artikel veranschaulichten Antworten handelt es sich um Beispiele.\n> Copilot Chat Antworten sind nicht deterministisch, daher erhalten Sie möglicherweise unterschiedliche Antworten von den hier gezeigten Antworten.\n\n## Vermeiden gleichzeitiger Updates in voneinander abhängigen Zeilen\n\nWenn zwei oder mehr Transaktionen versuchen, dieselben Zeilen in einer Datenbanktabelle zu aktualisieren, jedoch in unterschiedlicher Reihenfolge, kann dies zu einer zirkulären Wartebedingung führen.\n\n### Beispielszenario\n\nDer folgende SQL-Codeabschnitt aktualisiert eine Zeile einer Tabelle, führt dann eine Operation durch, die mehrere Sekunden dauert, und aktualisiert anschließend eine weitere Zeile in derselben Tabelle. Dies ist problematisch, weil die Transaktion die `id = 1`-Zeile mehrere Sekunden lang sperrt, bis dies Transaktion abgeschlossen wird, wodurch die Sperre gelöst wird. Wenn während dieser Zeit eine andere Transaktion beginnt, die einen ähnlichen Vorgang ausführt, die `id = 2`-Zeile jedoch zuerst sperrt und aktualisiert und dann versucht, die `id = 1`-Zeile zu sperren, werden beide Transaktionen auf den Abschluss der jeweils anderen warten, wodurch ein Deadlock entsteht.\n\n```sql id=deadlock-example\nBEGIN TRANSACTION;\nUPDATE my_table SET value = 'Some value' WHERE id = 301;\n-- Simulate a process taking 5 seconds:\nWAITFOR DELAY '00:00:05';\nUPDATE my_table SET value = 'Another value' WHERE id = 127;\nCOMMIT TRANSACTION;\n```\n\n### Beispielprompt 1\n\nSie können überprüfen, ob Probleme mit dieser Transaktion auftreten.\n\nWählen Sie im Editor den Transaktionscode aus, und fragen Sie dann:Copilot Chat\n\n```copilot copy prompt ref=deadlock-example\nIs this transaction good?\n```\n\n### Beispielantwort 1\n\nCopilot teilt Ihnen mit, dass \"die Transaktion in Ihrem SQL-Code in der Regel einwandfrei ist\", aber es werden einige Dinge aufgeführt, die Sie berücksichtigen sollten: Sperrdauer, Fehlerbehandlung und Parallelität. Copilot erwähnt auch, dass die Transaktion längere Sperren enthält, was potenziell zu Blockierungen oder Deadlocks führen kann.\" Die Antwort enthält auch überarbeiteten Code mit einer Fehlerbehandlung.\n\nIn diesem Fall entscheiden Sie sich jedoch, keine Fehlerbehandlung hinzuzufügen. Jetzt sollten Sie sich mit dem Potenzial für Deadlocks auseinandersetzen.\n\n### Beispielprompt 2\n\nGeben Sie diese Folgeäußerung ein:\n\n```copilot copy prompt ref=deadlock-example\nHow can I rewrite this code to reduce the chance of deadlock to a minimum while not adversely affecting performance. Tell me anything else I can do to avoid a deadlock. Note: I don't want to add error handling at this time.\n```\n\n### Beispielantwort 2\n\nCopilot gibt folgende Ratschläge:\n\n> *\n\n**Order of Access:** Stellen Sie sicher, dass alle Transaktionen auf Tabellen und Zeilen in derselben Reihenfolge zugreifen.\n\n> \\*\n> **Kurzhalten der Transaktionen:** Minimieren Sie die Sperrzeiten von Transaktionen.\n> \\*\n> **Verwenden der geeigneten Isolationsstufen:** Verwenden Sie die niedrigste Isolationsstufe, die Ihren Anforderungen entspricht.\n>\n> Hier ist eine überarbeitete Version Ihres Codes:\n\n```sql\nBEGIN TRANSACTION;\n-- Update the rows in a consistent order\nUPDATE my_table SET value = 'Another value' WHERE id = 127;\nUPDATE my_table SET value = 'Some value' WHERE id = 301;\n-- Simulate a process taking 5 seconds:\nWAITFOR DELAY '00:00:05';\nCOMMIT TRANSACTION;\n```\n\n## Vermeiden von Nicht-Index-Suchen\n\nDas Durchsuchen von nicht indizierten Tabellenspalten führt in der Regel zu einem vollständigen Tabellenscan. Dieser kann sehr langsam und ressourcenintensiv sein und die Wahrscheinlichkeit von Leistungsengpässen erhöhen.\n\n### Beispielszenario\n\nDer folgende SQL-Code führt zu einem vollständigen Tabellenscan, wenn `some_column` nicht indiziert wurde:\n\n```sql id=full-table-scan\nBEGIN TRANSACTION;\nSELECT * FROM my_table WHERE some_column = 'some_value';\n-- More actions here, then:\nCOMMIT TRANSACTION;\n```\n\n### Beispielaufforderung\n\nWenn Sie die folgende Frage stellen Copilot , wird in der Regel das potenzielle Problem offengelegt.\n\n```copilot copy prompt ref=full-table-scan\nHow can I optimize this transaction?\n```\n\n### Beispielantwort\n\nCopilot gibt einige Ratschläge und erwähnt, dass die Spalte indiziert werden sollte:\n\n> Um die Transaktion zu optimieren, sollten Sie sicherstellen, dass die Transaktion so kurz wie möglich ist, um Sperrungen zu reduzieren und die Leistung zu verbessern. Hier einige Tipps:\n>\n> 1.\n\n**Minimieren der in der Transaktion durchgeführten Tasks:** Nehmen Sie nur erforderliche Vorgänge in die Transaktion auf.\n\n> 1\\.\n> **Verwenden geeigneter Indizes:** Stellen Sie sicher, dass die in der WHERE-Klausel verwendeten Spalten indiziert sind.\n> 1\\.\n> **Vermeiden von lang andauernde Transaktionen:** Halten Sie die Transaktionsdauer kurz, um Probleme mit Sperrungen zu vermeiden.\n\nDer in der Antwort vorgeschlagene Code enthält den SQL-Befehl zum Indizieren der Spalte:\n\n```sql\n`CREATE INDEX idx_some_column ON my_table(some_column);`\n```\n\n## Vermeiden von zeitintensiven Transaktionen\n\nLang andauernde Abfragen und Transaktionen sollten nach Möglichkeit unbedingt vermieden werden, da sie die Leistung erheblich beeinträchtigen und Engpässe für andere Vorgänge verursachen können. Darüber hinaus können sie einen erheblichen Anteil des Arbeits- und Protokollspeichers verbrauchen, wodurch deine Anwendung in Umgebungen mit hoher Auslastung fehleranfälliger wird.\n\n### Beispielszenario\n\nDer folgende SQL-Code erstellt neue Zeilen in `target_table`, die Daten aus ausgewählten Zeilenfeldern in `source_table` enthalten, die verschiedene Bedingungen erfüllen. Wenn `source_table` besonders groß ist, kann dies zu einer lang andauernden Ausführung der Transaktion führen.\n\n```sql id=long-running-transaction\nBEGIN TRANSACTION;\n\nINSERT INTO target_table (first_name, last_name, email, dept, role, hire_date)\nSELECT first_name, last_name, email, department, job_title, start_date\nFROM source_table\nWHERE (department = 'Engineering' AND (salary > 95000 OR grade > 5))\n  OR (department = 'Marketing' AND performance_rating = 'Excellent');\n\nCOMMIT;\n```\n\n### Beispielaufforderung\n\nSie können bei Copilot nachfragen, ob es möglich ist, lang andauernde Transaktionen zu vermeiden.\n\n```copilot copy prompt ref=long-running-transaction\nsource_table is an extremely large table. Without altering the table, how can I ensure this SQL doesn't become a long-running query, that blocks other operations?\n```\n\n### Beispielantwort\n\nCopilot schlägt die folgenden Strategien vor:\n\n* **Batchverarbeitung:** Verarbeiten Sie die Daten in kleineren Batches anstelle einer einzelnen großen Transaktion. Dies kann mithilfe einer Schleife mit einem Grenzwert und einem Offset erfolgen.\n* **Indizierung:** Stellen Sie sicher, dass die in der `WHERE`-Klausel verwendeten Spalten (`department`, `salary`, `grade` und `performance_rating`) indiziert werden, um die Abfrage zu beschleunigen.\n* **Sperren:** Verwenden Sie die Sperrung auf Zeilenebene, um eine Sperrung der gesamten Tabelle zu vermeiden.\n\nCopilot liefert das folgende Beispiel für die Implementierung einer Batchverarbeitung. In diesem SQL-Code werden die Daten in Batches von jeweils 1.000 Zeilen verarbeitet, wodurch die Auslastung der Datenbank sinkt und lang andauernde Transaktionen vermieden werden.\n\n```sql\nDECLARE @BatchSize INT = 1000;\nDECLARE @Offset INT = 0;\nDECLARE @RowCount INT;\n\nSET @RowCount = @BatchSize;\n\nWHILE @RowCount = @BatchSize\nBEGIN\n    BEGIN TRANSACTION;\n\n    INSERT INTO target_table (first_name, last_name, email, dept, role, hire_date)\n    SELECT first_name, last_name, email, department, job_title, start_date\n    FROM source_table\n    WHERE (department = 'Engineering' AND salary > 95000)\n       OR (department = 'Engineering' AND years_of_experience > 5)\n       OR (department = 'Marketing' AND performance_rating = 'Excellent');\n    ORDER BY primary_key_column\n    OFFSET @Offset ROWS FETCH NEXT @BatchSize ROWS ONLY;\n\n    SET @RowCount = @@ROWCOUNT;\n    SET @Offset = @Offset + @BatchSize;\n\n    COMMIT;\nEND;\n```\n\nCopilot weist Sie an, `primary_key_column` durch den Namen der tatsächlichen Primärschlüsselspalte von `source_table` im vorgeschlagenen Code zu ersetzen.\n\n## Vermeiden von Datenintegritätsproblemen\n\nEs ist wichtig, dass die Informationen in Ihren Datenbanken korrekt, konsistent und vollständig bleiben. Mangelhaft konzipierte Abfragen können zu fehlenden oder falschen Daten führen.\n\n### Beispielszenario\n\nDie folgende SQL-Transaktion löscht einen Mitarbeiterdatensatz und erstellt ein Löschprotokoll. Es ist jedoch möglich, dass der `DELETE`-Vorgang erfolgreich verläuft, während der `INSERT`-Vorgang fehlschlägt. In diesem Fall gibt es keinen Protokolldatensatz für den Löschvorgang.\n\n```sql id=delete-employee\nBEGIN TRANSACTION;\n\nDELETE FROM employees\nWHERE employee_id = 101;\n\nINSERT INTO deletion_log (employee_id, deletion_date, reason)\nVALUES (101, GETDATE(), 'Voluntary Resignation');\n\nCOMMIT TRANSACTION;\n```\n\n### Beispielaufforderung\n\n```copilot copy prompt ref=delete-employee\nHow can I ensure that the DELETE and INSERT operations are only performed if both succeed?\n```\n\n### Beispielantwort\n\nCopilot zeigt Ihnen, dass Sie dies durch die Verwendung einer Transaktion mit Fehlerbehandlung erreichen. Im folgenden Beispiel wird das `TRY...CATCH`-Konstrukt von SQL Server verwendet:\n\n```sql\nBEGIN TRY\n    BEGIN TRANSACTION;\n\n    DELETE FROM employees\n    WHERE employee_id = 101;\n\n    INSERT INTO deletion_log (employee_id, deletion_date, reason)\n    VALUES (101, GETDATE(), 'Voluntary Resignation');\n\n    COMMIT TRANSACTION;\nEND TRY\nBEGIN CATCH\n    ROLLBACK TRANSACTION;\n    -- Handle the error, e.g., log it or re-throw\n    DECLARE @ErrorMessage NVARCHAR(4000);\n    DECLARE @ErrorSeverity INT;\n    DECLARE @ErrorState INT;\n\n    SELECT\n        @ErrorMessage = ERROR_MESSAGE(),\n        @ErrorSeverity = ERROR_SEVERITY(),\n        @ErrorState = ERROR_STATE();\n\n    RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);\nEND CATCH;\n```\n\nDer vorgeschlagene Code stellt sicher, dass die Transaktion zurückgesetzt wird und keine Änderungen an der Datenbank vorgenommen werden, wenn der `DELETE`- oder der `INSERT`-Vorgang fehlschlägt.\n\n## Weiterführende Lektüre\n\n* [Prompt-Engineering für GitHub Copilot Chat](/de/copilot/concepts/prompting/prompt-engineering)\n* [Bewährte Methoden für die Verwendung von GitHub Copilot](/de/copilot/get-started/best-practices)"}