Handbuch zu Transaktionssperren und ZeilenversionsverwaltungTransaction Locking and Row Versioning Guide

GILT FÜR: JaSQL Server JaAzure SQL-Datenbank JaAzure Synapse Analytics (SQL Data Warehouse) JaParallel Data Warehouse APPLIES TO: YesSQL Server YesAzure SQL Database YesAzure Synapse Analytics (SQL Data Warehouse) YesParallel Data Warehouse

In jeder Datenbank führt die fehlerhafte Verwaltung von Transaktionen bei Systemen mit zahlreichen Benutzern häufig zu Konflikten und Leistungsproblemen.In any database, mismanagement of transactions often leads to contention and performance problems in systems that have many users. Mit steigender Anzahl von Benutzern, die auf die Daten zugreifen, wird der Einsatz von Anwendungen, die Transaktionen effizient verwenden, immer wichtiger.As the number of users that access the data increases, it becomes important to have applications that use transactions efficiently. In diesem Handbuch werden Mechanismen für Sperren und die Zeilenversionsverwaltung beschrieben, durch die das SQL Server-Datenbank-EngineSQL Server Database Engine die physische Integrität jeder Transaktion sicherstellt. Darüber hinaus erfahren Sie, wie Transaktionen von Anwendungen effizient gesteuert werden.This guide describes the locking and row versioning mechanisms the SQL Server-Datenbank-EngineSQL Server Database Engine uses to ensure the physical integrity of each transaction and provides information on how applications can control transactions efficiently.

Gilt für: SQL ServerSQL Server (SQL Server 2005 (9.x)SQL Server 2005 (9.x) bis SQL Server 2019 (15.x)SQL Server 2019 (15.x), sofern nicht anders angegeben) und Azure SQL-DatenbankAzure SQL Database.Applies to: SQL ServerSQL Server (SQL Server 2005 (9.x)SQL Server 2005 (9.x) through SQL Server 2019 (15.x)SQL Server 2019 (15.x), unless noted otherwise) and Azure SQL-DatenbankAzure SQL Database.

Grundlagen zu TransaktionenTransaction Basics

Eine Transaktion ist eine Folge von Operationen, die als einzelne logische Arbeitseinheit ausgeführt wird.A transaction is a sequence of operations performed as a single logical unit of work. Eine logische Arbeitseinheit muss vier Eigenschaften aufweisen, die als ACID-Eigenschaften (Atomicity, Consistency, Isolation und Durability; Unteilbarkeit, Konsistenz, Isolation und Beständigkeit) bezeichnet werden, um als Transaktion zu gelten.A logical unit of work must exhibit four properties, called the atomicity, consistency, isolation, and durability (ACID) properties, to qualify as a transaction.

UnteilbarkeitAtomicity
Eine Transaktion muss eine unteilbare Arbeitseinheit sein; entweder werden alle durch sie vorgesehenen Datenänderungen oder keine der Änderungen ausgeführt.A transaction must be an atomic unit of work; either all of its data modifications are performed, or none of them are performed.

KonsistenzConsistency
Am Ende einer Transaktion müssen sich alle Daten in einem konsistenten Status befinden.When completed, a transaction must leave all data in a consistent state. In einer relationalen Datenbank müssen alle Regeln auf die Änderungen der Transaktion angewendet werden, um die Integrität aller Daten zu erhalten.In a relational database, all rules must be applied to the transaction's modifications to maintain all data integrity. Alle internen Datenstrukturen, wie B-Struktur-Indizes oder doppelt verknüpfte Listen, müssen am Ende der Transaktion richtig sein.All internal data structures, such as B-tree indexes or doubly-linked lists, must be correct at the end of the transaction.

IsolationIsolation
Änderungen, die von gleichzeitigen Transaktionen ausgeführt werden, müssen von allen Änderungen, die von anderen gleichzeitigen Transaktionen ausgeführt werden, isoliert sein.Modifications made by concurrent transactions must be isolated from the modifications made by any other concurrent transactions. Einer Transaktion stehen Daten entweder in dem Status zur Verfügung, in dem sie sich vor der Änderung durch eine andere gleichzeitige Transaktion befanden, oder in dem Status nach Beenden der zweiten Transaktion, jedoch nicht in einem Zwischenstatus.A transaction either recognizes data in the state it was in before another concurrent transaction modified it, or it recognizes the data after the second transaction has completed, but it does not recognize an intermediate state. Dies wird als Serialisierbarkeit bezeichnet, da sich daraus die Fähigkeit ableitet, die Ausgangsdaten erneut zu laden und eine Reihe von Transaktionen erneut durchzuführen, um schließlich die Daten in dem Status zu erhalten, der vorlag, nachdem die ursprünglichen Transaktionen ausgeführt wurden.This is referred to as serializability because it results in the ability to reload the starting data and replay a series of transactions to end up with the data in the same state it was in after the original transactions were performed.

DauerhaftigkeitDurability
Nach Abschluss einer voll beständigen Transaktion sind ihre Auswirkungen im System dauerhaft.After a fully durable transaction has completed, its effects are permanently in place in the system. Die Änderungen bleiben auch bei einem Systemfehler persistent.The modifications persist even in the event of a system failure. SQL Server 2014 (12.x)SQL Server 2014 (12.x) und höher ermöglichen verzögerte dauerhafte Transaktionen.and later enable delayed durable transactions. Für verzögerte dauerhafte Transaktionen wird ein Commit ausgeführt, bevor der Transaktionsprotokolldatensatz auf dem Datenträger beibehalten wird.Delayed durable transactions commit before the transaction log record is persisted to disk. Weitere Informationen zur Dauerhaftigkeit verzögerter Transaktionen finden Sie im Thema Transaktionsdauerhaftigkeit.For more information on delayed transaction durability see the topic Transaction Durability.

SQL-Programmierer sind dafür verantwortlich, Transaktionen an Punkten zu starten und zu beenden, die die logische Konsistenz der Daten erzwingen.SQL programmers are responsible for starting and ending transactions at points that enforce the logical consistency of the data. Der Programmierer muss die Sequenz der Datenänderungen so definieren, dass die Daten hinsichtlich der Geschäftsregeln der Organisation in konsistentem Status bleiben.The programmer must define the sequence of data modifications that leave the data in a consistent state relative to the organization's business rules. Daraufhin schließt der Programmierer diese Änderungsanweisungen in eine einzelne Transaktion ein, sodass SQL Server-Datenbank-EngineSQL Server Database Engine die physische Integrität der Transaktion erzwingen kann.The programmer includes these modification statements in a single transaction so that the SQL Server-Datenbank-EngineSQL Server Database Engine can enforce the physical integrity of the transaction.

Es ist die Aufgabe eines Unternehmensdatenbank-Systems, wie z. B. einer Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine, Mechanismen bereitzustellen, durch die die physische Integrität aller Transaktionen sichergestellt wird.It is the responsibility of an enterprise database system, such as an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine, to provide mechanisms ensuring the physical integrity of each transaction. SQL Server-Datenbank-EngineSQL Server Database Engine stellt Folgendes bereit:The SQL Server-Datenbank-EngineSQL Server Database Engine provides:

  • Sperrvorrichtungen, durch die die Isolation jeder Transaktion erhalten bleibt.Locking facilities that preserve transaction isolation.

  • Protokolliervorrichtungen stellen die Beständigkeit von Transaktionen sicher.Logging facilities ensure transaction durability. Bei vollständig dauerhaften Transaktionen wird der Protokolldatensatz vor dem Transaktionscommit auf den Datenträger geschrieben.For fully durable transactions the log record is hardened to disk before the transactions commits. Bei einem Fehler der Serverhardware, des Betriebssystems oder der Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine selbst verwendet die Instanz nach dem Neustart die Transaktionsprotokolle, um automatisch einen Rollback für alle nicht beendeten Transaktionen auszuführen, der sie auf ihren Status vor dem Systemfehler zurücksetzt.Thus, even if the server hardware, operating system, or the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine itself fails, the instance uses the transaction logs upon restart to automatically roll back any incomplete transactions to the point of the system failure. Für verzögerte dauerhafte Transaktionen wird ein Commit ausgeführt, bevor der Transaktionsprotokolldatensatz auf dem Datenträger gespeichert wird.Delayed durable transactions commit before the transaction log record is hardened to disk. Solche Transaktionen gehen möglicherweise verloren, wenn ein Systemfehler auftritt, bevor die Protokolldatensätze auf dem Datenträger gespeichert werden.Such transactions may be lost if there is a system failure before the log record is hardened to disk. Weitere Informationen zur Dauerhaftigkeit verzögerter Transaktionen finden Sie im Thema Transaktionsdauerhaftigkeit.For more information on delayed transaction durability see the topic Transaction Durability.

  • Funktionen der Transaktionsverwaltung, die die Unteilbarkeit und Konsistenz der Transaktionen erzwingen.Transaction management features that enforce transaction atomicity and consistency. Nach Beginn einer Transaktion muss die Transaktion erfolgreich (mit einem Commit) beendet werden, da die SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz sonst alle Datenänderungen rückgängig macht, die seit Beginn der Transaktion ausgeführt wurden.After a transaction has started, it must be successfully completed (committed), or the SQL Server-Datenbank-EngineSQL Server Database Engine undoes all of the data modifications made since the transaction started. Dieser Vorgang wird als Rollback einer Transaktion bezeichnet, da die Daten in den Zustand zurückversetzt werden, der vor den Änderungen gültig war.This operation is referred to as rolling back a transaction because it returns the data to the state it was prior to those changes.

Steuern von TransaktionenControlling Transactions

Transaktionen werden von Anwendungen hauptsächlich durch Angeben der Zeitpunkte für Transaktionsbeginn und -ende gesteuert.Applications control transactions mainly by specifying when a transaction starts and ends. Die Steuerung kann über Transact-SQLTransact-SQL-Anweisungen oder Datenbank-API-Funktionen erfolgen.This can be specified by using either Transact-SQLTransact-SQL statements or database application programming interface (API) functions. Das System muss auch in der Lage sein, Fehler richtig zu behandeln, die eine Transaktion vor deren Abschluss beenden.The system must also be able to correctly handle errors that terminate a transaction before it completes. Weitere Informationen finden Sie unter Transaktionen, Transaktionen in ODBC und Transaktionen in SQL Server Native Client (OLEDB).For more information, see Transactions, Transactions in ODBC and Transactions in SQL Server Native Client (OLEDB).

Standardmäßig werden Transaktionen auf der Verbindungsebene verwaltet.By default, transactions are managed at the connection level. Wenn eine Transaktion über eine Verbindung gestartet wird, sind alle Transact-SQLTransact-SQL-Anweisungen, die über diese Verbindung ausgeführt werden, Teil der Transaktion, bis diese endet.When a transaction is started on a connection, all Transact-SQLTransact-SQL statements executed on that connection are part of the transaction until the transaction ends. In einer MARS-Sitzung (Multiple Active Result Set) wird eine explizite oder implizite Transact-SQLTransact-SQL-Transaktion jedoch zu einer Transaktion mit Batchbereich, die auf der Batchebene verwaltet wird.However, under a multiple active result set (MARS) session, a Transact-SQLTransact-SQL explicit or implicit transaction becomes a batch-scoped transaction that is managed at the batch level. Wenn der Batch abgeschlossen wird, führt SQL ServerSQL Server automatisch einen Rollback aus, wenn für die Transaktion mit Batchbereich kein Commit oder Rollback ausgeführt wurde.When the batch completes, if the batch-scoped transaction is not committed or rolled back, it is automatically rolled back by SQL ServerSQL Server. Weitere Informationen finden Sie unter Verwenden von Multiple Active Result Sets (MARS).For more information, see Using Multiple Active Result Sets (MARS).

Starten von TransaktionenStarting Transactions

Mithilfe von API-Funktionen und Transact-SQLTransact-SQL-Anweisungen können Sie Transaktionen in einer Instanz des SQL Server-Datenbank-EngineSQL Server Database Engine als explizite, implizite oder Autocommit-Transaktionen starten.Using API functions and Transact-SQLTransact-SQL statements, you can start transactions in an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine as explicit, autocommit, or implicit transactions.

Explizite TransaktionenExplicit Transactions
Eine explizite Transaktion ist eine Transaktion, in der Sie sowohl den Beginn als auch das Ende der Transaktion über eine API-Funktion oder durch Ausgabe einer der Transact-SQLTransact-SQL-Anweisungen BEGIN TRANSACTION, COMMIT TRANSACTION, COMMIT WORK oder ROLLBACK TRANSACTION bzw. der ROLLBACK WORK-Anweisungen (Transact-SQLTransact-SQL) explizit festlegen.An explicit transaction is one in which you explicitly define both the start and end of the transaction through an API function or by issuing the Transact-SQLTransact-SQL BEGIN TRANSACTION, COMMIT TRANSACTION, COMMIT WORK, ROLLBACK TRANSACTION, or ROLLBACK WORK Transact-SQLTransact-SQL statements. Am Ende der Transaktion kehrt die Verbindung zu dem Transaktionsmodus zurück, in dem sie sich vor Beginn der expliziten Transaktion befand, also entweder zum impliziten oder zum Autocommitmodus.When the transaction ends, the connection returns to the transaction mode it was in before the explicit transaction was started, either implicit or autocommit mode.

Sie können alle Transact-SQLTransact-SQL-Anweisungen in einer expliziten Transaktion verwenden; ausgenommen davon sind die folgenden Anweisungen:You can use all Transact-SQLTransact-SQL statements in an explicit transaction, except for the following statements:

ALTER DATABASEALTER DATABASE CREATE DATABASECREATE DATABASE DROP FULLTEXT INDEXDROP FULLTEXT INDEX
ALTER FULLTEXT CATALOGALTER FULLTEXT CATALOG CREATE FULLTEXT CATALOGCREATE FULLTEXT CATALOG RECONFIGURERECONFIGURE
ALTER FULLTEXT INDEXALTER FULLTEXT INDEX CREATE FULLTEXT INDEXCREATE FULLTEXT INDEX RESTORERESTORE
BACKUPBACKUP DROP DATABASEDROP DATABASE Gespeicherte Volltext-SystemprozedurenFull-text system stored procedures
CREATE DATABASECREATE DATABASE DROP FULLTEXT CATALOGDROP FULLTEXT CATALOG sp_dboption zum Festlegen von Datenbankoptionen oder einer beliebigen Systemprozedur, durch die die Masterdatenbank in expliziten bzw. impliziten Transaktionen geändert wird.sp_dboption to set database options or any system procedure that modifies the master database inside explicit or implicit transactions.

Hinweis

UPDATE STATISTICS kann in einer expliziten Transaktion verwendet werden.UPDATE STATISTICS can be used inside an explicit transaction. UPDATE STATISTICS führt jedoch unabhängig von der einschließenden Transaktion einen Commit aus, und es kann kein Rollback ausgeführt werden.However, UPDATE STATISTICS commits independently of the enclosing transaction and cannot be rolled back.

Autocommit-TransaktionenAutocommit Transactions
Der Autocommit-Modus ist der Standardmodus zur Transaktionsverwaltung von SQL Server-Datenbank-EngineSQL Server Database Engine.Autocommit mode is the default transaction management mode of the SQL Server-Datenbank-EngineSQL Server Database Engine. Für jede Transact-SQLTransact-SQL-Anweisung wird beim Beenden ein Commit oder Rollback ausgeführt.Every Transact-SQLTransact-SQL statement is committed or rolled back when it completes. Wenn eine Anweisung erfolgreich beendet wird, wird ein Commit ausgeführt; wenn hingegen Fehler auftreten, wird ein Rollback ausgeführt.If a statement completes successfully, it is committed; if it encounters any error, it is rolled back. Eine Verbindung mit einer Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine befindet sich immer dann im Autocommit-Modus, wenn dieser Standardmodus nicht durch explizite oder implizite Transaktionen überschrieben wird.A connection to an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine operates in autocommit mode whenever this default mode has not been overridden by either explicit or implicit transactions. Der Autocommit-Modus ist ebenfalls der Standardmodus für ADO, OLE DB, ODBC und DB-Library.Autocommit mode is also the default mode for ADO, OLE DB, ODBC, and DB-Library.

Implizite TransaktionenImplicit Transactions
Wenn eine Verbindung sich im impliziten Transaktionsmodus befindet, startet SQL Server-Datenbank-EngineSQL Server Database Engine automatisch eine neue Transaktion, nachdem für die aktuelle Transaktion ein Commit oder Rollback ausgeführt wurde.When a connection is operating in implicit transaction mode, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine automatically starts a new transaction after the current transaction is committed or rolled back. Die Kennzeichnung des Starts einer Transaktion entfällt; Sie führen nur einen Commit oder Rollback für die einzelnen Transaktionen aus.You do nothing to delineate the start of a transaction; you only commit or roll back each transaction. Im impliziten Transaktionsmodus wird eine fortlaufende Kette von Transaktionen generiert.Implicit transaction mode generates a continuous chain of transactions. Sie legen den impliziten Transaktionsmodus entweder durch eine API-Funktion oder durch die Transact-SQLTransact-SQL-Anweisung SET IMPLICIT_TRANSACTIONS ON fest.Set implicit transaction mode on through either an API function or the Transact-SQLTransact-SQL SET IMPLICIT_TRANSACTIONS ON statement. Dieser Modus wird auch Autocommit OFF genannt. Weitere Informationen finden Sie unter setAutoCommit-Methode.This mode is also known as Autocommit OFF, see setAutoCommit Method in JDBC

Nachdem der implizite Transaktionsmodus für eine Verbindung aktiviert wurde, startet SQL Server-Datenbank-EngineSQL Server Database Engine automatisch eine Transaktion, wenn eine dieser Anweisungen zum ersten Mal ausgeführt wird:After implicit transaction mode has been set on for a connection, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine automatically starts a transaction when it first executes any of these statements:

ALTER TABLEALTER TABLE FETCHFETCH REVOKEREVOKE
CREATECREATE GRANTGRANT SELECTSELECT
DeleteDELETE INSERTINSERT TRUNCATE TABLETRUNCATE TABLE
DROPDROP OPENOPEN UPDATEUPDATE
  • Transaktionen mit BatchbereichBatch-scoped Transactions
    Trifft nur auf MARS (Multiple Active Result Sets) zu; eine explizite oder implizite Transact-SQLTransact-SQL-Transaktion, die unter einer MARS-Sitzung gestartet wird, wird zu einer Transaktion im Batchbereich.Applicable only to multiple active result sets (MARS), a Transact-SQLTransact-SQL explicit or implicit transaction that starts under a MARS session becomes a batch-scoped transaction. Für eine Transaktionen mit Batchbereich, für die nach Abschluss des Batches kein Commit oder Rollback ausgeführt wird, wird das Rollback automatisch durch SQL ServerSQL Server vorgenommen.A batch-scoped transaction that is not committed or rolled back when a batch completes is automatically rolled back by SQL ServerSQL Server.

  • Distributed Transactions (Verteilte Transaktionen)Distributed Transactions
    Verteilte Transaktionen erstrecken sich auf mindestens zwei Server, die als Ressourcen-Manager bekannt sind.Distributed transactions span two or more servers known as resource managers. Die Verwaltung der Transaktionen muss zwischen den Ressourcen-Managern von einer Serverkomponente, dem Transaktions-Manager, koordiniert werden.The management of the transaction must be coordinated between the resource managers by a server component called a transaction manager. Jede SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz kann als Ressourcen-Manager in verteilten Transaktionen eingesetzt werden, die von Transaktions-Managern, wie MicrosoftMicrosoft Distributed Transaction Coordinator (MS DTC) oder anderen Transaktions-Managern, die die Open Group XA-Spezifikation für die verteilte Transaktionsverarbeitung unterstützen, koordiniert werden.Each instance of the SQL Server-Datenbank-EngineSQL Server Database Engine can operate as a resource manager in distributed transactions coordinated by transaction managers, such as MicrosoftMicrosoft Distributed Transaction Coordinator (MS DTC), or other transaction managers that support the Open Group XA specification for distributed transaction processing. Weitere Informationen finden Sie in der MS DTC-Dokumentation.For more information, see the MS DTC documentation.

    Eine Transaktion auf einem einzelnen Computer mit SQL Server-Datenbank-EngineSQL Server Database Engine die sich auf mindestens zwei Datenbanken erstreckt, ist tatsächlich eine verteilte Transaktion.A transaction within a single instance of the SQL Server-Datenbank-EngineSQL Server Database Engine that spans two or more databases is actually a distributed transaction. Die Instanz verwaltet die verteilte Transaktion jedoch intern; für den Benutzer entsteht der Eindruck, es handele sich um eine lokale Transaktion.The instance manages the distributed transaction internally; to the user, it operates as a local transaction.

    Auf der Anwendungsebene wird eine verteilte Transaktion beinahe so wie eine lokale Transaktion verwaltet.At the application, a distributed transaction is managed much the same as a local transaction. Am Ende der Transaktion fordert die Anwendung die Transaktion auf, entweder einen Commit oder Rollback auszuführen.At the end of the transaction, the application requests the transaction to be either committed or rolled back. Ein verteilter Commit darf vom Transaktions-Manager nicht auf dieselbe Art verwaltet werden, um das Risiko zu minimieren, dass einige Ressourcen-Manager bei einem Netzwerkfehler den Commit erfolgreich ausführen, während andere für die Transaktion einen Rollback ausführen.A distributed commit must be managed differently by the transaction manager to minimize the risk that a network failure may result in some resource managers successfully committing while others roll back the transaction. Dies wird dadurch erreicht, dass der Commitvorgang in zwei Phasen verwaltet wird (die Vorbereitungsphase und die Commitphase), bekannt als Zweiphasencommit (2PC).This is achieved by managing the commit process in two phases (the prepare phase and the commit phase), which is known as a two-phase commit (2PC).

    • VorbereitungsphasePrepare phase
      Wenn der Transaktions-Manager eine Anforderung für ein Commit erhält, sendet er einen Vorbereitungsbefehl an alle Ressourcen-Manager, die an der Transaktion beteiligt sind.When the transaction manager receives a commit request, it sends a prepare command to all of the resource managers involved in the transaction. Jeder Ressourcen-Manager trifft dann die notwendigen Vorbereitungen, um die Transaktion beständig zu machen, und alle Puffer, die Images von Protokollen für die Transaktion enthalten, werden auf den Datenträger geleert.Each resource manager then does everything required to make the transaction durable, and all buffers holding log images for the transaction are flushed to disk. Wenn die Ressourcen-Manager die Vorbereitungsphase beenden, geben sie jeweils eine Information über den Erfolg oder das Fehlschlagen der Vorbereitung an den Transaktions-Manager zurück.As each resource manager completes the prepare phase, it returns success or failure of the prepare to the transaction manager. Mit SQL Server 2014 (12.x)SQL Server 2014 (12.x) wurde die verzögerte Transaktionsdauerhaftigkeit eingeführt.SQL Server 2014 (12.x)SQL Server 2014 (12.x) introduced delayed transaction durability. Für verzögerte dauerhafte Transaktionen wird ein Commit ausgeführt, bevor das Protokollimage auf den Datenträger geleert wird.Delayed durable transactions commit before log images for the transaction are flushed to disk. Weitere Informationen zur Dauerhaftigkeit verzögerter Transaktionen finden Sie im Thema Transaktionsdauerhaftigkeit.For more information on delayed transaction durability see the topic Transaction Durability.

    • CommitphaseCommit phase
      Wenn der Transaktions-Manager von der erfolgreichen Vorbereitung aller Ressourcen-Manager in Kenntnis gesetzt wird, sendet er Commitbefehle an alle Ressourcen-Manager.If the transaction manager receives successful prepares from all of the resource managers, it sends commit commands to each resource manager. Die Ressourcen-Manager können dann den Commit beenden.The resource managers can then complete the commit. Wenn alle Ressourcen-Manager eine erfolgreiche Ausführung des Commits melden, sendet der Transaktions-Manager eine Benachrichtigung über die erfolgreiche Ausführung an die Anwendung.If all of the resource managers report a successful commit, the transaction manager then sends a success notification to the application. Wenn einer der Ressourcen-Manager einen Fehler bei der Vorbereitung ausgibt, sendet der Transaktions-Manager einen Rollbackbefehl an alle Ressourcen-Manager und benachrichtigt die Anwendung über die fehlgeschlagene Ausführung des Commits.If any resource manager reported a failure to prepare, the transaction manager sends a rollback command to each resource manager and indicates the failure of the commit to the application.

      SQL Server-Datenbank-EngineSQL Server Database Engine-Anwendungen können verteilte Transaktionen entweder über Transact-SQLTransact-SQL oder die Datenbank-API verwalten.applications can manage distributed transactions either through Transact-SQLTransact-SQL or the database API. Weitere Informationen finden Sie unter BEGIN DISTRIBUTED TRANSACTION (Transact-SQL).For more information, see BEGIN DISTRIBUTED TRANSACTION (Transact-SQL).

Beenden von TransaktionenEnding Transactions

Sie können Transaktionen entweder mit einer COMMIT-Anweisung oder ROLLBACK-Anweisung oder durch eine entsprechende API-Funktion beenden.You can end transactions with either a COMMIT or ROLLBACK statement, or through a corresponding API function.

  • COMMITCOMMIT
    Wenn eine Transaktion erfolgreich ist, führen Sie einen Commit aus.If a transaction is successful, commit it. Durch eine COMMIT-Anweisung wird sichergestellt, dass alle Änderungen der Transaktion zum dauerhaften Bestandteil der Datenbank werden.A COMMIT statement guarantees all of the transaction's modifications are made a permanent part of the database. Durch eine COMMIT-Anweisung werden auch von der Transaktion verwendete Ressourcen, wie etwa Sperren, freigegeben.A COMMIT also frees resources, such as locks, used by the transaction.

  • ROLLBACKROLLBACK
    Wenn ein Fehler in einer Transaktion auftritt, oder wenn ein Benutzer beschließt, die Transaktion abzubrechen, führen Sie ein Rollback aus.If an error occurs in a transaction, or if the user decides to cancel the transaction, then roll the transaction back. Durch eine ROLLBACK-Anweisung werden alle Änderungen, die während der Transaktion vorgenommen wurden, rückgängig gemacht, sodass die Daten in ihren Ausgangsstatus zurückversetzt werden.A ROLLBACK statement backs out all modifications made in the transaction by returning the data to the state it was in at the start of the transaction. Durch das ROLLBACK werden auch Ressourcen freigegeben, die von der Transaktion beansprucht wurden.A ROLLBACK also frees resources held by the transaction.

Hinweis

Bei Verbindungen, die für die Unterstützung von MARS (Multiple Active Result Sets) aktiviert sind, kann für eine durch eine API-Funktion gestartete explizite Transaktion kein Commit ausgeführt werden, solange Ausführungsanforderungen anstehen.Under connections enabled to support multiple active result sets (MARS), an explicit transaction started through an API function cannot be committed while there are pending requests for execution. Jeder Versuch, ein Commit für eine derartige Transaktion auszuführen, für die noch ausstehende Vorgänge vorhanden sind, führt zu einem Fehler.Any attempt to commit this type of transaction while there are outstanding operations running will result in an error.

Fehler während der TransaktionsverarbeitungErrors During Transaction Processing

Wenn eine Transaktion aufgrund eines Fehlers nicht erfolgreich beendet werden kann, führt SQL ServerSQL Server automatisch ein Rollback für die Transaktion aus und gibt alle Ressourcen frei, die von der Transaktion beansprucht wurden.If an error prevents the successful completion of a transaction, SQL ServerSQL Server automatically rolls back the transaction and frees all resources held by the transaction. Wenn die Netzwerkverbindung des Clients mit einer Instanz des SQL Server-Datenbank-EngineSQL Server Database Engine unterbrochen ist, wird für alle ausstehenden Transaktionen dieser Verbindung ein Rollback ausgeführt, sobald das Netzwerk die Instanz über die Unterbrechung benachrichtigt.If the client's network connection to an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine is broken, any outstanding transactions for the connection are rolled back when the network notifies the instance of the break. Wenn die Clientanwendung einen Fehler erzeugt oder wenn der Clientcomputer heruntergefahren oder neu gestartet wird, kommt es ebenfalls zu einer Unterbrechung der Verbindung, und die Instanz des SQL Server-Datenbank-EngineSQL Server Database Engine führt ein Rollback für alle ausstehenden Verbindungen aus, sobald das Netzwerk es über die Unterbrechung benachrichtigt.If the client application fails or if the client computer goes down or is restarted, this also breaks the connection, and the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine rolls back any outstanding connections when the network notifies it of the break. Wenn sich der Client von der Anwendung abmeldet, wird für alle ausstehenden Transaktionen ein Rollback ausgeführt.If the client logs off the application, any outstanding transactions are rolled back.

Wenn ein Anweisungsfehler zur Laufzeit (wie etwa eine Einschränkungsverletzung) in einem Batch auftritt, führt das SQL Server-Datenbank-EngineSQL Server Database Engine standardmäßig nur für die Anweisung ein Rollback aus, die den Fehler generiert hat.If a run-time statement error (such as a constraint violation) occurs in a batch, the default behavior in the SQL Server-Datenbank-EngineSQL Server Database Engine is to roll back only the statement that generated the error. Sie können dieses Verhalten mithilfe der SET XACT_ABORT-Anweisung ändern.You can change this behavior using the SET XACT_ABORT statement. Nach dem Ausführen von SET XACT_ABORT ON führt jeder Anweisungsfehler zur Laufzeit dazu, dass automatisch ein Rollback für die aktuelle Transaktion ausgeführt wird.After SET XACT_ABORT ON is executed, any run-time statement error causes an automatic rollback of the current transaction. Kompilierungsfehler, wie z.B. Syntaxfehler, sind von SET XACT_ABORT nicht betroffen.Compile errors, such as syntax errors, are not affected by SET XACT_ABORT. Weitere Informationen finden Sie unter SET XACT_ABORT (Transact-SQL).For more information, see SET XACT_ABORT (Transact-SQL).

Für den Fall, dass Fehler auftreten, sollte in den Anwendungscode eine korrigierende Aktion (COMMIT oder ROLLBACK) aufgenommen werden.When errors occur, corrective action (COMMIT or ROLLBACK) should be included in application code. Das Transact-SQLTransact-SQL-Konstrukt TRY...CATCH ist ein effektives Tool für die Fehlerbehandlung, einschließlich der Behandlung von Fehlern in Transaktionen.One effective tool for handling errors, including those in transactions, is the Transact-SQLTransact-SQL TRY...CATCH construct. Weitere Informationen mit Beispielen zu Transaktionen finden Sie unter TRY...CATCH (Transact-SQL).For more information with examples that include transactions, see TRY...CATCH (Transact-SQL). Ab SQL Server 2012 (11.x)SQL Server 2012 (11.x) kann die THROW-Anweisung verwendet werden, um eine Ausnahme auszulösen und die Ausführung an einen CATCH-Block eines TRY...CATCH-Konstrukts zu übergeben.Beginning with SQL Server 2012 (11.x)SQL Server 2012 (11.x), you can use the THROW statement to raise an exception and transfers execution to a CATCH block of a TRY...CATCH construct. Weitere Informationen finden Sie unter THROW (Transact-SQL).For more information, see THROW (Transact-SQL).

Kompilierungs- und Laufzeitfehler im Autocommit-ModusCompile and Run-time Errors in Autocommit mode

Im Autocommit-Modus entsteht hin und wieder der Eindruck, dass eine SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz ein Rollback für einen gesamten Batch und nicht nur für eine einzelne SQL-Anweisung ausgeführt hat.In autocommit mode, it sometimes appears as if an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine has rolled back an entire batch instead of just one SQL statement. Dies passiert, wenn es sich beim aufgetretenen Fehler um einen Kompilierungsfehler und nicht um einen Laufzeitfehler handelt.This happens if the error encountered is a compile error, not a run-time error. Bei einem Kompilierungsfehler wird verhindert, dass SQL Server-Datenbank-EngineSQL Server Database Engine einen Ausführungsplan erstellt; somit wird keine Anweisung im Batch ausgeführt.A compile error prevents the SQL Server-Datenbank-EngineSQL Server Database Engine from building an execution plan, so nothing in the batch is executed. Obwohl der Eindruck entsteht, dass für alle Anweisungen vor derjenigen, die den Fehler generiert hat, ein Rollback ausgeführt wurde, hat der Fehler bereits verhindert, dass überhaupt eine Anweisung im Batch ausgeführt wurde.Although it appears that all of the statements before the one generating the error were rolled back, the error prevented anything in the batch from being executed. Im folgenden Beispiel wird aufgrund eines Kompilierungsfehlers keine der INSERT-Anweisungen im dritten Batch ausgeführt.In the following example, none of the INSERT statements in the third batch are executed because of a compile error. Es entsteht der Eindruck, dass für die ersten zwei INSERT-Anweisungen ein Rollback ausgeführt wird, obwohl sie nie ausgeführt wurden.It appears that the first two INSERT statements are rolled back when they are never executed.

CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));  
GO  
INSERT INTO TestBatch VALUES (1, 'aaa');  
INSERT INTO TestBatch VALUES (2, 'bbb');  
INSERT INTO TestBatch VALUSE (3, 'ccc');  -- Syntax error.  
GO  
SELECT * FROM TestBatch;  -- Returns no rows.  
GO  

Im folgenden Beispiel generiert die dritte INSERT-Anweisung einen Laufzeitfehler aufgrund eines doppelten Primärschlüssels.In the following example, the third INSERT statement generates a run-time duplicate primary key error. Die ersten zwei INSERT-Anweisungen sind erfolgreich, sodass für sie ein Commit ausgeführt wird; sie bleiben somit nach dem Laufzeitfehler erhalten.The first two INSERT statements are successful and committed, so they remain after the run-time error.

CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));  
GO  
INSERT INTO TestBatch VALUES (1, 'aaa');  
INSERT INTO TestBatch VALUES (2, 'bbb');  
INSERT INTO TestBatch VALUES (1, 'ccc');  -- Duplicate key error.  
GO  
SELECT * FROM TestBatch;  -- Returns rows 1 and 2.  
GO  

SQL Server-Datenbank-EngineSQL Server Database Engine verwendet die verzögerte Namensauflösung, bei der Objektnamen erst zur Ausführungszeit aufgelöst werden.The SQL Server-Datenbank-EngineSQL Server Database Engine uses deferred name resolution, in which object names are not resolved until execution time. Im folgenden Beispiel werden die ersten zwei INSERT-Anweisungen ausgeführt und mit einem Commit abgeschlossen; die entsprechenden beiden Zeilen bleiben in der TestBatch-Tabelle, nachdem die dritte INSERT-Anweisung einen Laufzeitfehler durch Verweisen auf eine nicht vorhandene Tabelle generiert.In the following example, the first two INSERT statements are executed and committed, and those two rows remain in the TestBatch table after the third INSERT statement generates a run-time error by referring to a table that does not exist.

CREATE TABLE TestBatch (Cola INT PRIMARY KEY, Colb CHAR(3));  
GO  
INSERT INTO TestBatch VALUES (1, 'aaa');  
INSERT INTO TestBatch VALUES (2, 'bbb');  
INSERT INTO TestBch VALUES (3, 'ccc');  -- Table name error.  
GO  
SELECT * FROM TestBatch;  -- Returns rows 1 and 2.  
GO  

Grundlagen zu Sperren und ZeilenversionsverwaltungLocking and Row Versioning Basics

SQL Server-Datenbank-EngineSQL Server Database Engine verwendet die folgenden Mechanismen, um die Integrität von Transaktionen sicherzustellen und die Konsistenz der Datenbanken beizubehalten, wenn mehrere Benutzer gleichzeitig auf Daten zugreifen:The SQL Server-Datenbank-EngineSQL Server Database Engine uses the following mechanisms to ensure the integrity of transactions and maintain the consistency of databases when multiple users are accessing data at the same time:

  • SperrenLocking

    Jede Transaktion fordert Sperren verschiedener Typen für die Ressourcen (wie z. B. Zeilen, Seiten oder Tabellen) an, von denen die Transaktion abhängt.Each transaction requests locks of different types on the resources, such as rows, pages, or tables, on which the transaction is dependent. Diese Sperren verhindern, dass die Ressourcen durch andere Transaktionen in einer Weise geändert werden, die zu Problemen für die Transaktion führen würde, die die Sperre angefordert hat.The locks block other transactions from modifying the resources in a way that would cause problems for the transaction requesting the lock. Jede Transaktion hebt ihre Sperren wieder auf, sobald sie nicht mehr von den gesperrten Ressourcen abhängig ist.Each transaction frees its locks when it no longer has a dependency on the locked resources.

  • ZeilenversionsverwaltungRow versioning

    Wenn eine auf Zeilenversionsverwaltung basierende Isolationsstufe aktiviert ist, bewahrt SQL Server-Datenbank-EngineSQL Server Database Engine Versionen jeder Zeile auf, an der Änderungen vorgenommen werden.When a row versioning-based isolation level is enabled, the SQL Server-Datenbank-EngineSQL Server Database Engine maintains versions of each row that is modified. Anwendungen können angeben, dass eine Transaktion die Zeilenversionen verwendet, um die Daten so anzuzeigen, wie sie zum Zeitpunkt des Transaktions- oder Abfragestarts vorgelegen haben, statt alle Lesevorgänge durch Sperren zu schützen.Applications can specify that a transaction use the row versions to view data as it existed at the start of the transaction or query instead of protecting all reads with locks. Durch Verwendung der Zeilenversionsverwaltung wird die Wahrscheinlichkeit, dass ein Lesevorgang zur Blockierung anderer Transaktionen führt, weitgehend reduziert.By using row versioning, the chance that a read operation will block other transactions is greatly reduced.

Sperren und Zeilenversionsverwaltung verhindern, dass Benutzer Daten lesen, für die noch kein Commit ausgeführt wurde, und verhindern, dass viele Benutzer gleichzeitig versuchen, dieselben Daten zu ändern.Locking and row versioning prevent users from reading uncommitted data and prevent multiple users from attempting to change the same data at the same time. Ohne Sperren oder Zeilenversionsverwaltung könnten Abfragen, die für Daten ausgeführt werden, zu unerwarteten Ergebnissen führen, weil Daten zurückgegeben werden, für die in der Datenbank noch kein Commit ausgeführt wurde.Without locking or row versioning, queries executed against that data could produce unexpected results by returning data that has not yet been committed in the database.

Anwendungen können Transaktionsisolationsstufen auswählen. Diese Stufen definieren, inwieweit die jeweilige Transaktion vor Datenänderungen durch andere Transaktionen geschützt ist.Applications can choose transaction isolation levels, which define the level of protection for the transaction from modifications made by other transactions. Für einzelne Transact-SQLTransact-SQL-Anweisungen können Hinweise auf Tabellenebene angegeben werden, um das Verhalten noch weiter an die Anforderungen der Anwendung anzupassen.Table-level hints can be specified for individual Transact-SQLTransact-SQL statements to further tailor behavior to fit the requirements of the application.

Verwalten des parallelen DatenzugriffsManaging Concurrent Data Access

Wenn Benutzer zum selben Zeitpunkt auf eine Ressource zugreifen, wird das als paralleler Zugriff auf die Ressource bezeichnet.Users who access a resource at the same time are said to be accessing the resource concurrently. Der parallele Datenzugriff erfordert Mechanismen, mit denen negative Auswirkungen vermieden werden, wenn mehrere Benutzer versuchen, Ressourcen zu ändern, die von anderen Benutzern aktiv verwendet werden.Concurrent data access requires mechanisms to prevent adverse effects when multiple users try to modify resources that other users are actively using.

ParallelitätseffekteConcurrency Effects

Benutzer, die Daten ändern, können einen Konflikt mit anderen Benutzern verursachen, die die gleichen Daten zur gleichen Zeit lesen oder ändern.Users modifying data can affect other users who are reading or modifying the same data at the same time. Durch diese Benutzer erfolgt ein gleichzeitiger Zugriff auf die Daten.These users are said to be accessing the data concurrently. Wenn ein Datenspeichersystem keine Steuerung für die Parallelität besitzt, können Benutzer die folgenden Auswirkungen feststellen:If a data storage system has no concurrency control, users could see the following side effects:

  • Verlorene UpdatesLost updates

    Verlorene Updates treten auf, wenn mindestens zwei Transaktionen dieselbe Zeile auswählen und diese Zeile dann auf der Grundlage des ursprünglich ausgewählten Werts aktualisieren.Lost updates occur when two or more transactions select the same row and then update the row based on the value originally selected. Eine einzelne Transaktion ist nicht über die anderen Transaktionen informiert.Each transaction is unaware of the other transactions. Das letzte Update überschreibt Updates von anderen Transaktionen; dies führt zu Datenverlusten.The last update overwrites updates made by the other transactions, which results in lost data.

    Nehmen Sie beispielsweise an, dass zwei Redakteure eine elektronische Kopie desselben Dokuments erstellen.For example, two editors make an electronic copy of the same document. Jeder Redakteur ändert die eigene Kopie und speichert die geänderte Kopie anschließend, wodurch das Originaldokument überschrieben wird.Each editor changes the copy independently and then saves the changed copy thereby overwriting the original document. Der Redakteur, der die Kopie zuletzt speichert, überschreibt die Änderungen des anderen Redakteurs.The editor who saves the changed copy last overwrites the changes made by the other editor. Das Problem könnte vermieden werden, wenn einer der Redakteure erst auf die Datei zugreifen kann, nachdem der andere Redakteur seine Arbeit beendet und ein Commit der Transaktion ausgeführt hat.This problem could be avoided if one editor could not access the file until the other editor had finished and committed the transaction.

  • Abhängigkeit von Daten, für die kein Commit ausgeführt wurde (Dirty Read)Uncommitted dependency (dirty read)

    Die Abhängigkeit von Daten, für die kein Commit ausgeführt wurde, tritt dann ein, wenn eine zweite Transaktion eine Zeile auswählt, die von einer anderen Transaktion aktualisiert wird.Uncommitted dependency occurs when a second transaction selects a row that is being updated by another transaction. Die zweite Transaktion liest Daten, für die noch kein Commit ausgeführt wurde und die von der Transaktion, die die Zeile aktualisiert, noch geändert werden können.The second transaction is reading data that has not been committed yet and may be changed by the transaction updating the row.

    Angenommen, ein Redakteur nimmt Änderungen an einem elektronischen Dokument vor.For example, an editor is making changes to an electronic document. Während die Änderungen vorgenommen werden, verteilt ein zweiter Redakteur eine Kopie des Dokuments mit allen bisherigen Änderungen an die Zielgruppe.During the changes, a second editor takes a copy of the document that includes all the changes made so far, and distributes the document to the intended audience. Der erste Redakteur entscheidet dann, dass die bisherigen Änderungen falsch sind, löscht sie und speichert das Dokument.The first editor then decides the changes made so far are wrong and removes the edits and saves the document. Das verteilte Dokument enthält nun Änderungen, die nicht mehr vorhanden sind und so behandelt werden müssten, als ob sie nie vorhanden gewesen wären.The distributed document contains edits that no longer exist and should be treated as if they never existed. Dieses Problem könnte vermieden werden, wenn das geänderte Dokument erst dann gelesen werden könnte, wenn der erste Redakteur die endgültige Speicherung der Änderungen vorgenommen und ein Commit der Transaktion ausgeführt hat.This problem could be avoided if no one could read the changed document until the first editor does the final save of modifications and commits the transaction.

  • Inkonsistente Analyse (nicht wiederholbarer Lesevorgang)Inconsistent analysis (nonrepeatable read)

    Die inkonsistente Analyse tritt dann ein, wenn eine zweite Transaktion mehrmals auf dieselbe Zeile zugreift und jedes Mal verschiedene Daten liest.Inconsistent analysis occurs when a second transaction accesses the same row several times and reads different data each time. Die inkonsistente Analyse ist vergleichbar mit der Abhängigkeit von Daten, für die kein Commit ausgeführt wurde, da auch in diesem Fall eine andere Transaktion die Daten ändert, die eine zweite Transaktion liest.Inconsistent analysis is similar to uncommitted dependency in that another transaction is changing the data that a second transaction is reading. Bei der inkonsistenten Analyse wurde jedoch für die von der zweiten Transaktion gelesenen Daten ein Commit von der Transaktion, die die Änderung vornahm, ausgeführt.However, in inconsistent analysis, the data read by the second transaction was committed by the transaction that made the change. Darüber hinaus umfasst die inkonsistente Analyse mehrere Lesevorgänge (mindestens zwei) derselben Zeile, wobei jedes Mal die Informationen von einer anderen Transaktion geändert wurden; der Begriff "Nicht wiederholbarer Lesevorgang" bezieht sich auf diesen Vorgang.Also, inconsistent analysis involves multiple reads (two or more) of the same row, and each time the information is changed by another transaction; thus, the term nonrepeatable read.

    Angenommen, ein Redakteur liest dasselbe Dokument zweimal, doch zwischen den einzelnen Lesedurchgängen schreibt der Verfasser das Dokument um.For example, an editor reads the same document twice, but between each reading the writer rewrites the document. Wenn der Redakteur das Dokument zum zweiten Mal liest, unterscheidet es sich von der ersten Version.When the editor reads the document for the second time, it has changed. Der ursprüngliche Lesevorgang lässt sich nicht wiederholen.The original read was not repeatable. Dieses Problem könnte vermieden werden, wenn der Verfasser das Dokument erst ändern könnte, nachdem der Redakteur den letzten Lesevorgang beendet hat.This problem could be avoided if the writer could not change the document until the editor has finished reading it for the last time.

  • PhantomlesezugriffePhantom reads

    Ein Phantomlesezugriff ist eine Situation, bei der zwei identische Abfragen ausgeführt werden, wobei die von der zweiten Abfrage zurückgegebene Zeilensammlung abweicht.A phantom read is a situation that occurs when two identical queries are executed and the collection of rows returned by the second query is different. Im unten stehenden Beispiel wird veranschaulicht, wie eine solche Situation auftreten kann.The example below shows how this may occur. Angenommen, die beiden unten stehenden Transaktionen werden gleichzeitig ausgeführt.Assume the two transactions below are executing at the same time. Die zwei SELECT-Anweisungen in der ersten Transaktion können ggf. andere Ergebnisse zurückgeben, da die INSERT-Anweisung in der zweiten Transaktion die von beiden verwendeten Daten ändert.The two SELECT statements in the first transaction may return different results because the INSERT statement in the second transaction changes the data used by both.

    --Transaction 1  
    BEGIN TRAN;  
    SELECT ID FROM dbo.employee  
    WHERE ID > 5 and ID < 10;  
    --The INSERT statement from the second transaction occurs here.  
    SELECT ID FROM dbo.employee  
    WHERE ID > 5 and ID < 10;  
    COMMIT;  
    
    --Transaction 2  
    BEGIN TRAN;  
    INSERT INTO dbo.employee  
      (Id, Name) VALUES(6 ,'New');  
    COMMIT;   
    
  • Durch Zeilenupdates verursachte fehlende und doppelte LesezugriffeMissing and double reads caused by row updates

    • Übergehen einer aktualisierten Zeile oder mehrfaches Erkennen einer aktualisierten ZeileMissing a updated row or seeing an updated row multiple times

      Transaktionen, die auf der READ UNCOMMITTED-Ebene ausgeführt werden, geben keine freigegebenen Sperren aus, die verhindern würden, dass andere Transaktionen Daten ändern, die von der aktuellen Transaktion gelesen werden.Transactions that are running at the READ UNCOMMITTED level do not issue shared locks to prevent other transactions from modifying data read by the current transaction. Transaktionen, die auf der READ COMMITTED-Ebene ausgeführt werden, geben freigegebene Sperren aus. Diese Zeilen- oder Seitensperren werden jedoch aufgehoben, nachdem die Zeile gelesen wurde.Transactions that are running at the READ COMMITTED level do issue shared locks, but the row or page locks are released after the row is read. In beiden Fällen kann beim Scannen eines Index eine Zeile zwei Mal erscheinen, wenn ein anderer Benutzer die Indexschlüsselspalte ändert, während Sie sie lesen, und die Spalte durch die Schlüsseländerung an eine Position hinter der aktuellen Leseposition verschoben wird.In either case, when you are scanning an index, if another user changes the index key column of the row during your read, the row might appear again if the key change moved the row to a position ahead of your scan. Ebenso ist es möglich, dass die Zeile nicht erscheint, wenn die Spalte durch die Schlüsseländerung an eine Indexposition verschoben wird, die bereits gelesen wurde.Similarly, the row might not appear if the key change moved the row to a position in the index that you had already read. Um dies zu vermeiden, verwenden Sie den SERIALIZABLE- oder HOLDLOCK-Hinweis oder die Zeilenversionsverwaltung.To avoid this, use the SERIALIZABLE or HOLDLOCK hint, or row versioning. Weitere Informationen finden Sie unter Tabellenhinweise (Transact-SQL).For more information, see Table Hints (Transact-SQL).

    • Übergehen von Zeilen, die nicht Ziel von Updates warenMissing one or more rows that were not the target of update

      Wenn READ UNCOMMITTED angegeben wird und eine Abfrage Zeilen in der Speicherreservierungsreihenfolge (unter Verwendung der IAM-Seiten) liest, werden möglicherweise Zeilen übergangen, falls eine Seite durch eine andere Transaktion geteilt wird.When you are using READ UNCOMMITTED, if your query reads rows using an allocation order scan (using IAM pages), you might miss rows if another transaction is causing a page split. Dieser Fall kann beim Einsatz von READ UNCOMMITTED nicht eintreten, weil während der Teilung einer Seite eine Tabellensperre aufrechterhalten wird. Es werden auch keine Zeilen übergangen, wenn die Tabelle nicht über einen gruppierten Index verfügt, da Updates keine Seitenteilungen verursachen.This cannot occur when you are using read committed because a table lock is held during a page split and does not happen if the table does not have a clustered index, because updates do not cause page splits.

ParallelitätstypenTypes of Concurrency

Wenn viele Benutzer gleichzeitig versuchen, Daten in einer Datenbank zu ändern, muss ein Steuerungssystem implementiert werden, durch das sichergestellt wird, dass sich die von einem Benutzer vorgenommenen Änderungen nicht auf die Änderungen eines anderen Benutzers auswirken.When many people attempt to modify data in a database at the same time, a system of controls must be implemented so that modifications made by one person do not adversely affect those of another person. Dies wird als Parallelitätssteuerung bezeichnet.This is called concurrency control.

In der Theorie der Parallelitätssteuerung werden die Methoden zum Implementieren der Parallelitätssteuerung in zwei Gruppen klassifiziert:Concurrency control theory has two classifications for the methods of instituting concurrency control:

  • Steuerung durch eingeschränkte ParallelitätPessimistic concurrency control

    Durch ein System aus Sperren werden Benutzer daran gehindert, Daten so zu verändern, dass sich dies nachteilig auf die Arbeit anderer Benutzer auswirkt.A system of locks prevents users from modifying data in a way that affects other users. Sobald ein Benutzer eine Aktion ausführt, die zum Anwenden einer Sperre führt, können andere Benutzer so lange keine Aktionen ausführen, die mit dieser Sperre in Konflikt stehen, bis die Sperre durch den Besitzer aufgehoben wird.After a user performs an action that causes a lock to be applied, other users cannot perform actions that would conflict with the lock until the owner releases it. Diese Vorgehensweise wird als Steuerung durch eingeschränkte Parallelität bezeichnet und wird vorwiegend in Umgebungen verwendet, in denen die Wahrscheinlichkeit von Konflikten beim Zugriff auf Daten sehr hoch ist. In diesen Umgebungen verursacht das Schützen der Daten mithilfe von Sperren weniger Kosten als das Ausführen von Rollbacks für Transaktionen, wenn Parallelitätskonflikte aufgetreten sind.This is called pessimistic control because it is mainly used in environments where there is high contention for data, where the cost of protecting data with locks is less than the cost of rolling back transactions if concurrency conflicts occur.

  • Steuerung durch vollständige ParallelitätOptimistic concurrency control

    Bei der Steuerung durch vollständige Parallelität werden keine Sperren für Daten eingerichtet, wenn diese von den Benutzern gelesen werden.In optimistic concurrency control, users do not lock data when they read it. Wenn ein Benutzer Daten aktualisiert, überprüft das System, ob ein anderer Benutzer die Daten geändert hat, nachdem sie gelesen wurden.When a user updates data, the system checks to see if another user changed the data after it was read. Wenn die Daten bereits durch einen anderen Benutzer aktualisiert worden sind, wird ein Fehler ausgelöst.If another user updated the data, an error is raised. In der Regel führt der Benutzer, der die Fehlermeldung empfangen hat, einen Rollback für die Transaktion aus und beginnt mit der Bearbeitung von vorn.Typically, the user receiving the error rolls back the transaction and starts over. Diese Vorgehensweise wird als Steuerung durch vollständige Parallelität bezeichnet und wird vorwiegend in Umgebungen verwendet, in denen nur wenige Konflikte beim Zugriff auf Daten entstehen und die Kosten für das gelegentliche Ausführen von Rollbacks für eine Transaktion geringer sind als die Kosten für das Sperren der Daten, wenn sie gelesen werden.This is called optimistic because it is mainly used in environments where there is low contention for data, and where the cost of occasionally rolling back a transaction is lower than the cost of locking data when read.

SQL ServerSQL Server unterstützt verschiedene Typen der Parallelitätssteuerung.supports a range of concurrency control. Benutzer geben den Typ der Parallelitätssteuerung an, indem sie Transaktionsisolationsstufen für Verbindungen oder Parallelitätsoptionen für Cursor angeben.Users specify the type of concurrency control by selecting transaction isolation levels for connections or concurrency options on cursors. Diese Attribute können mithilfe von Transact-SQLTransact-SQL-Anweisungen definiert werden oder über die Eigenschaften und Attribute der Schnittstellen zur Anwendungsprogrammierung (APIs, Application Programming Interfaces) der Datenbank, wie z. B. ADO, ADO.NET, OLE DB und ODBC.These attributes can be defined using Transact-SQLTransact-SQL statements, or through the properties and attributes of database application programming interfaces (APIs) such as ADO, ADO.NET, OLE DB, and ODBC.

Isolationsstufen im SQL Server-Datenbank-EngineSQL Server Database EngineIsolation Levels in the SQL Server-Datenbank-EngineSQL Server Database Engine

Transaktionen geben eine Isolationsstufe an, mit der definiert wird, bis zu welchem Ausmaß eine Transaktion von Ressourcen- oder Datenänderungen isoliert sein muss, die von anderen Transaktionen durchgeführt werden.Transactions specify an isolation level that defines the degree to which one transaction must be isolated from resource or data modifications made by other transactions. Die einzelnen Isolationsstufen werden dahingehend beschrieben, welche Parallelitätsnebeneffekte (wie z. B. Dirty Reads oder Phantomlesezugriffe) zulässig sind.Isolation levels are described in terms of which concurrency side-effects, such as dirty reads or phantom reads, are allowed.

Durch die Transaktionsisolationsstufen wird Folgendes gesteuert:Transaction isolation levels control:

  • Ob beim Lesen von Daten Sperren aktiviert werden können, und welcher Sperrentyp angefordert wird.Whether locks are taken when data is read, and what type of locks are requested.
  • Wie lange die Lesesperren aufrechterhalten werden.How long the read locks are held.
  • Ob ein Lesevorgang, der auf Zeilen verweist, die durch eine andere Transaktion geändert wurden:Whether a read operation referencing rows modified by another transaction:
    • Blockiert wird, bis die exklusive Sperre für die Zeile aufgehoben wird.Blocks until the exclusive lock on the row is freed.
    • Die durch einen Commit bestätigte Version der Zeile abruft, die zum Zeitpunkt des Anweisungs- oder Transaktionsstarts vorhanden war.Retrieves the committed version of the row that existed at the time the statement or transaction started.
    • Die Datenänderung liest, für die noch kein Commit ausgeführt wurde.Reads the uncommitted data modification.

Wichtig

Das Auswählen einer Transaktionsisolationsstufe hat keine Auswirkungen auf die Sperren, die zum Schutz der Datenänderung eingerichtet werden.Choosing a transaction isolation level does not affect the locks acquired to protect data modifications. Eine Transaktion erhält immer eine exklusive Sperre für alle von ihr geänderten Daten und hält diese Sperre bis zum Abschluss der Transaktion aufrecht, und zwar unabhängig davon, welche Isolationsstufe für diese Transaktion festgelegt wurde.A transaction always gets an exclusive lock on any data it modifies, and holds that lock until the transaction completes, regardless of the isolation level set for that transaction. Für Lesevorgänge wird durch die Transaktionsisolationsstufen in erster Linie der Grad des Schutzes vor den Auswirkungen der Änderungen definiert, die durch andere Transaktionen vorgenommen werden.For read operations, transaction isolation levels primarily define the level of protection from the effects of modifications made by other transactions.

Eine niedrigere Isolationsstufe erhöht einerseits die Möglichkeit, dass viele Benutzer gleichzeitig auf Daten zugreifen können, führt aber gleichzeitig zum Anstieg der negativen Parallelitätseffekte (Dirty Reads oder verlorene Updates), mit denen die Benutzer rechnen müssten.A lower isolation level increases the ability of many users to access data at the same time, but increases the number of concurrency effects (such as dirty reads or lost updates) users might encounter. Und umgekehrt schränkt eine höhere Isolationsstufe zwar die Typen der Parallelitätseffekte ein, mit denen Benutzer rechnen müssen, gleichzeitig werden dafür aber mehr Systemressourcen beansprucht, und die Wahrscheinlichkeit steigt, dass sich die Transaktionen untereinander blockieren.Conversely, a higher isolation level reduces the types of concurrency effects that users may encounter, but requires more system resources and increases the chances that one transaction will block another. So muss bei jeder Auswahl der geeigneten Isolationsstufe eine Abwägung zwischen den Datenintegritätsanforderungen der Anwendungen einerseits und dem mit jeder Isolationsstufe verbundenen Aufwand andererseits erfolgen.Choosing the appropriate isolation level depends on balancing the data integrity requirements of the application against the overhead of each isolation level. Die höchste Isolationsstufe (Serializable) garantiert, dass eine Transaktion jedes Mal, wenn sie einen Lesevorgang wiederholt, genau dieselben Daten liest. Dies wird jedoch durch ein Ausmaß an Sperren erreicht, das in Systemen mit mehreren Benutzern wahrscheinlich zu negativen Auswirkungen für andere Benutzer führt.The highest isolation level, serializable, guarantees that a transaction will retrieve exactly the same data every time it repeats a read operation, but it does this by performing a level of locking that is likely to impact other users in multi-user systems. Mit der niedrigsten Isolationsstufe (Read Uncommitted) können Daten abgerufen werden, die von anderen Transaktionen geändert wurden, für die jedoch noch kein Commit ausgeführt wurde.The lowest isolation level, read uncommitted, may retrieve data that has been modified but not committed by other transactions. In der Isolationsstufe Read Uncommitted können sämtliche denkbaren Parallelitätsnebeneffekte auftreten, dagegen werden keine Lesesperren und keine Versionsverwaltung verwendet, wodurch der Aufwand minimiert wird.All of the concurrency side effects can happen in read uncommitted, but there is no read locking or versioning, so overhead is minimized.

Isolationsstufen der Datenbank-EngineDatabase Engine Isolation Levels

Der ISO-Standard definiert die folgenden Isolationsstufen, die alle von SQL Server-Datenbank-EngineSQL Server Database Engine unterstützt werden:The ISO standard defines the following isolation levels, all of which are supported by the SQL Server-Datenbank-EngineSQL Server Database Engine:

IsolationsstufeIsolation Level DefinitionDefinition
Read uncommittedRead uncommitted Die niedrigste Isolationsstufe, bei der Transaktionen nur soweit isoliert werden, dass sichergestellt ist, dass keine physisch beschädigten Daten gelesen werden.The lowest isolation level where transactions are isolated only enough to ensure that physically corrupt data is not read. Auf dieser Stufe sind Dirty Reads zulässig, d. h., eine Transaktion kann Änderungen verfolgen, die von anderen Transaktionen vorgenommen wurden und für die noch kein Commit ausgeführt wurde.In this level, dirty reads are allowed, so one transaction may see not-yet-committed changes made by other transactions.
Read committedRead committed Ermöglicht einer Transaktion das Lesen von Daten, die zuvor von einer anderen Transaktion gelesen (nicht geändert) wurden, ohne warten zu müssen, bis die erste Transaktion abgeschlossen ist.Allows a transaction to read data previously read (not modified) by another transaction without waiting for the first transaction to complete. Das SQL Server-Datenbank-EngineSQL Server Database Engine behält Schreibsperren (die für ausgewählte Daten angefordert wurden) bis zum Ende der Transaktion bei, Lesesperren werden jedoch bei Ausführung des SELECT-Vorgangs freigegeben.The SQL Server-Datenbank-EngineSQL Server Database Engine keeps write locks (acquired on selected data) until the end of the transaction, but read locks are released as soon as the SELECT operation is performed. Dies ist die SQL Server-Datenbank-EngineSQL Server Database Engine-Standardstufe.This is the SQL Server-Datenbank-EngineSQL Server Database Engine default level.
Repeatable readRepeatable read Das SQL Server-Datenbank-EngineSQL Server Database Engine behält Lese- und Schreibsperren, die für ausgewählte Daten angefordert wurden, bis zum Ende der Transaktion bei.The SQL Server-Datenbank-EngineSQL Server Database Engine keeps read and write locks that are acquired on selected data until the end of the transaction. Da Bereichssperren jedoch nicht verwaltet werden, können Phantomlesevorgänge auftreten.However, because range-locks are not managed, phantom reads can occur.
SerializableSerializable Die höchste Stufe, auf der Transaktionen vollständig voneinander isoliert sind.The highest level where transactions are completely isolated from one another. Das SQL Server-Datenbank-EngineSQL Server Database Engine behält Lese- und Schreibsperren, die für ausgewählte Daten angefordert wurden, bis zur Freigabe am Ende der Transaktion bei.The SQL Server-Datenbank-EngineSQL Server Database Engine keeps read and write locks acquired on selected data to be released at the end of the transaction. Bereichssperren werden angefordert, wenn ein SELECT-Vorgang eine WHERE-Bereichsklausel verwendet. Dies dient vor allem der Vermeidung von Phantomlesevorgängen.Range-locks are acquired when a SELECT operation uses a ranged WHERE clause, especially to avoid phantom reads.

Hinweis: DDL-Vorgänge und -Transaktionen in replizierten Tabellen schlagen möglicherweise fehl, wenn die Isolationsstufe „Serializable“ angefordert wird.Note: DDL operations and transactions on replicated tables may fail when serializable isolation level is requested. Das liegt daran, dass Replikationsabfragen Hinweise verwenden, die möglicherweise mit der serialisierbaren Isolationsstufe nicht kompatibel sind.This is because replication queries use hints that may be incompatible with serializable isolation level.

SQL ServerSQL Server unterstützt außerdem zwei zusätzliche Transaktionsisolationsstufen, bei denen die Zeilenversionsverwaltung verwendet wird.also supports two additional transaction isolation levels that use row versioning. Eine davon ist eine Implementierung der Read Committed-Isolation, die andere – Snapshot – ist eine Transaktionsisolationsstufe.One is an implementation of read committed isolation, and one is a transaction isolation level, snapshot.

Isolationsstufe der ZeilenversionsverwaltungRow Versioning Isolation Level DefinitionDefinition
READ COMMITTED-Momentaufnahme (RCSI)Read Committed Snapshot (RCSI) Wenn die READ_COMMITTED_SNAPSHOT-Datenbankoption auf ON festgelegt ist, verwendet die READ COMMITTED-Isolation die Zeilenversionsverwaltung, um eine Lesekonsistenz auf der Anweisungsebene zu gewährleisten.When the READ_COMMITTED_SNAPSHOT database option is set ON, read committed isolation uses row versioning to provide statement-level read consistency. Lesevorgänge erfordern dabei lediglich SCH-S-Sperren auf der Tabellenebene und keine Seiten- oder Zeilensperren.Read operations require only SCH-S table level locks and no page or row locks. Das heißt, das SQL Server-Datenbank-EngineSQL Server Database Engine verwendet die Zeilenversionsverwaltung, um jede Anweisung mit einer transaktionskonsistenten Momentaufnahme der Daten so darzustellen, wie sie zu Beginn der Anweisung vorhanden waren.That is, the SQL Server-Datenbank-EngineSQL Server Database Engine uses row versioning to present each statement with a transactionally consistent snapshot of the data as it existed at the start of the statement. Es werden keine Sperren verwendet, um die Daten vor Updates durch andere Transaktionen zu schützen.Locks are not used to protect the data from updates by other transactions. Eine benutzerdefinierte Funktion kann Daten zurückgeben, für die ein Commit ausgeführt wurde, nachdem die Anweisung mit dem UDF begonnen hat.A user-defined function can return data that was committed after the time the statement containing the UDF began.

Wenn die Datenbankoption READ_COMMITTED_SNAPSHOT die Standardeinstellung OFF aufweist, verwendet die Read Committed-Isolation freigegebene Sperren, um zu verhindern, dass andere Transaktionen Zeilen ändern, während die aktuelle Transaktion einen Lesevorgang ausführt.When the READ_COMMITTED_SNAPSHOT database option is set OFF, which is the default setting, read committed isolation uses shared locks to prevent other transactions from modifying rows while the current transaction is running a read operation. Durch freigegebene Sperren wird außerdem verhindert, dass die Anweisung Zeilen, die von anderen Transaktionen geändert werden, erst nach Abschluss der anderen Transaktion lesen kann.The shared locks also block the statement from reading rows modified by other transactions until the other transaction is completed. Beide Implementierungen entsprechen der ISO-Definition der Read Committed-Isolation.Both implementations meet the ISO definition of read committed isolation.
MomentaufnahmeSnapshot Die Momentaufnahmeisolationsstufe verwendet die Zeilenversionsverwaltung, um die Lesekonsistenz auf der Transaktionsebene zu gewährleisten.The snapshot isolation level uses row versioning to provide transaction-level read consistency. Dabei werden durch Lesevorgänge keine Seiten- oder Zeilensperren eingerichtet, sondern lediglich SCH-S-Tabellensperren.Read operations acquire no page or row locks; only SCH-S table locks are acquired. Beim Lesen von Zeilen, die durch eine andere Transaktion geändert wurden, wird die Version der Zeile abgerufen, die zum Startzeitpunkt der Transaktion vorhanden war.When reading rows modified by another transaction, they retrieve the version of the row that existed when the transaction started. Sie können die Momentaufnahmeisolation für eine Datenbank nur verwenden, wenn die ALLOW_SNAPSHOT_ISOLATION-Datenbankoption auf ON festgelegt wurde.You can only use Snapshot isolation against a database when the ALLOW_SNAPSHOT_ISOLATION database option is set ON. Standardmäßig ist diese Option für Benutzerdatenbanken auf OFF gesetzt.By default, this option is set OFF for user databases.

Hinweis: SQL ServerSQL Server unterstützt die Versionsverwaltung von Metadaten nicht.Note: SQL ServerSQL Server does not support versioning of metadata. Aus diesem Grund gibt es bezüglich der DDL-Vorgänge, die in einer unter Momentaufnahmeisolation ausgeführten expliziten Transaktion ausgeführt werden, Einschränkungen.For this reason, there are restrictions on what DDL operations can be performed in an explicit transaction that is running under snapshot isolation. Die folgenden DDL-Anweisungen sind bei der Momentaufnahme-Isolationsstufe nach einer BEGIN TRANSACTION-Anweisung nicht zulässig: ALTER TABLE, CREATE INDEX, CREATE XML INDEX, ALTER INDEX, DROP INDEX, DBCC REINDEX, ALTER PARTITION FUNCTION, ALTER PARTITION SCHEME oder eine beliebige CLR-DDL-Anweisung (Common Language Runtime).The following DDL statements are not permitted under snapshot isolation after a BEGIN TRANSACTION statement: ALTER TABLE, CREATE INDEX, CREATE XML INDEX, ALTER INDEX, DROP INDEX, DBCC REINDEX, ALTER PARTITION FUNCTION, ALTER PARTITION SCHEME, or any common language runtime (CLR) DDL statement. Diese Anweisungen sind zulässig, wenn Sie die Momentaufnahmeisolation in impliziten Transaktionen verwenden.These statements are permitted when you are using snapshot isolation within implicit transactions. Eine implizite Transaktion ist definitionsgemäß eine einzelne Anweisung, mit der die Semantik der Momentaufnahmeisolation auch in DDL-Anweisungen erzwungen werden kann.An implicit transaction, by definition, is a single statement that makes it possible to enforce the semantics of snapshot isolation, even with DDL statements. Verstöße gegen dieses Prinzip können zu Fehler 3961 führen: Snapshot isolation transaction failed in database '%.*ls' because the object accessed by the statement has been modified by a DDL statement in another concurrent transaction since the start of this transaction. It is not allowed because the metadata is not versioned. A concurrent update to metadata could lead to inconsistency if mixed with snapshot isolation..Violations of this principle can cause error 3961: Snapshot isolation transaction failed in database '%.*ls' because the object accessed by the statement has been modified by a DDL statement in another concurrent transaction since the start of this transaction. It is not allowed because the metadata is not versioned. A concurrent update to metadata could lead to inconsistency if mixed with snapshot isolation.

Die folgende Tabelle veranschaulicht, welche Parallelitätsnebeneffekte in den einzelnen Isolationsstufen möglich sind.The following table shows the concurrency side effects enabled by the different isolation levels.

IsolationsstufeIsolation level Dirty ReadDirty read Nonrepeatable ReadNonrepeatable read PhantomPhantom
Read uncommittedRead uncommitted JaYes JaYes JaYes
Read committedRead committed NeinNo JaYes JaYes
Repeatable readRepeatable read NeinNo NeinNo JaYes
MomentaufnahmeSnapshot NeinNo NeinNo NeinNo
SerializableSerializable NeinNo NeinNo NeinNo

Weitere Informationen zu den speziellen Sperrentypen sowie zur Unterstützung der Zeilenversionsverwaltung durch die einzelnen Transaktionsisolationsstufen finden Sie unter SET TRANSACTION ISOLATION LEVEL (Transact-SQL).For more information about the specific types of locking or row versioning controlled by each transaction isolation level, see SET TRANSACTION ISOLATION LEVEL (Transact-SQL).

Die Isolationsstufen von Transaktionen können mithilfe von Transact-SQLTransact-SQL oder durch eine Datenbank-API festgelegt werden.Transaction isolation levels can be set using Transact-SQLTransact-SQL or through a database API.

Transact-SQLTransact-SQL
Transact-SQLTransact-SQL-Skripts verwenden die SET TRANSACTION ISOLATION LEVEL-Anweisung.scripts use the SET TRANSACTION ISOLATION LEVEL statement.

ADOADO
ADO-Anwendungen legen die IsolationLevel-Eigenschaft des Connection-Objekts auf „adXactReadUncommitted“, „adXactReadCommitted“, „adXactRepeatableRead“ oder „adXactReadSerializable“ fest.ADO applications set the IsolationLevel property of the Connection object to adXactReadUncommitted, adXactReadCommitted, adXactRepeatableRead, or adXactReadSerializable.

ADO.NETADO.NET
ADO.NET-Anwendungen, die den verwalteten Namespace System.Data.SqlClient verwenden, können die SqlConnection.BeginTransaction-Methode aufrufen und die Option IsolationLevel auf Unspecified, Chaos, ReadUncommitted, ReadCommitted, RepeatableRead, Serializable oder Momentaufnahme festlegen.ADO.NET applications using the System.Data.SqlClient managed namespace can call the SqlConnection.BeginTransaction method and set the IsolationLevel option to Unspecified, Chaos, ReadUncommitted, ReadCommitted, RepeatableRead, Serializable, and Snapshot.

OLE DBOLE DB
Beim Start einer Transaktion rufen Anwendungen, die OLE DB verwenden, ITransactionLocal::StartTransaction auf, wobei isoLevel auf ISOLATIONLEVEL_READUNCOMMITTED, ISOLATIONLEVEL_READCOMMITTED, ISOLATIONLEVEL_REPEATABLEREAD, ISOLATIONLEVEL_SNAPSHOT oder ISOLATIONLEVEL_SERIALIZABLE festgelegt ist.When starting a transaction, applications using OLE DB call ITransactionLocal::StartTransaction with isoLevel set to ISOLATIONLEVEL_READUNCOMMITTED, ISOLATIONLEVEL_READCOMMITTED, ISOLATIONLEVEL_REPEATABLEREAD, ISOLATIONLEVEL_SNAPSHOT, or ISOLATIONLEVEL_SERIALIZABLE.

Wenn die Isolationsstufe von Transaktionen im Autocommitmodus angegeben wird, können OLE DB-Anwendungen die DBPROPSET_SESSION-Eigenschaft DBPROP_SESS_AUTOCOMMITISOLEVELS auf DBPROPVAL_TI_CHAOS, DBPROPVAL_TI_READUNCOMMITTED, DBPROPVAL_TI_BROWSE, DBPROPVAL_TI_CURSORSTABILITY, DBPROPVAL_TI_READCOMMITTED, DBPROPVAL_TI_REPEATABLEREAD, DBPROPVAL_TI_SERIALIZABLE, DBPROPVAL_TI_ISOLATED oder DBPROPVAL_TI_SNAPSHOT festlegen.When specifying the transaction isolation level in autocommit mode, OLE DB applications can set the DBPROPSET_SESSION property DBPROP_SESS_AUTOCOMMITISOLEVELS to DBPROPVAL_TI_CHAOS, DBPROPVAL_TI_READUNCOMMITTED, DBPROPVAL_TI_BROWSE, DBPROPVAL_TI_CURSORSTABILITY, DBPROPVAL_TI_READCOMMITTED, DBPROPVAL_TI_REPEATABLEREAD, DBPROPVAL_TI_SERIALIZABLE, DBPROPVAL_TI_ISOLATED, or DBPROPVAL_TI_SNAPSHOT.

ODBCODBC
ODBC-Anwendungen rufen SQLSetConnectAttr auf, wobei Attribute auf SQL_ATTR_TXN_ISOLATION und ValuePtr auf SQL_TXN_READ_UNCOMMITTED, SQL_TXN_READ_COMMITTED, SQL_TXN_REPEATABLE_READ oder SQL_TXN_SERIALIZABLE festgelegt sind.ODBC applications call SQLSetConnectAttr with Attribute set to SQL_ATTR_TXN_ISOLATION and ValuePtr set to SQL_TXN_READ_UNCOMMITTED, SQL_TXN_READ_COMMITTED, SQL_TXN_REPEATABLE_READ, or SQL_TXN_SERIALIZABLE.

Für Momentaufnahmetransaktionen rufen Anwendungen SQLSetConnectAttr auf, wobei „Attribute“ auf SQL_COPT_SS_TXN_ISOLATION und „ValuePtr“ auf SQL_TXN_SS_SNAPSHOT festgelegt sind.For snapshot transactions, applications call SQLSetConnectAttr with Attribute set to SQL_COPT_SS_TXN_ISOLATION and ValuePtr set to SQL_TXN_SS_SNAPSHOT. Eine Momentaufnahmetransaktion kann mit SQL_COPT_SS_TXN_ISOLATION oder SQL_ATTR_TXN_ISOLATION abgerufen werden.A snapshot transaction can be retrieved using either SQL_COPT_SS_TXN_ISOLATION or SQL_ATTR_TXN_ISOLATION.

Sperren in der Datenbank-EngineLocking in the Database Engine

Sperren beschreiben einen Mechanismus, der von SQL Server-Datenbank-EngineSQL Server Database Engine zum Synchronisieren des gleichzeitigen Benutzerzugriffs auf die gleichen Daten verwendet wird.Locking is a mechanism used by the SQL Server-Datenbank-EngineSQL Server Database Engine to synchronize access by multiple users to the same piece of data at the same time.

Bevor eine Transaktion eine Abhängigkeit für den aktuellen Status von Daten abruft, z. B. durch Lesen oder Ändern der Daten, muss sie sich selbst vor den Auswirkungen schützen, die sich ergeben können, wenn eine andere Transaktion die gleichen Daten ändert.Before a transaction acquires a dependency on the current state of a piece of data, such as by reading or modifying the data, it must protect itself from the effects of another transaction modifying the same data. Die Transaktion fordert zu diesem Zweck eine Sperre für die betreffenden Daten an.The transaction does this by requesting a lock on the piece of data. Sperren besitzen verschiedene Modi, z. B. freigegeben oder exklusiv.Locks have different modes, such as shared or exclusive. Der Sperrmodus definiert den Grad der Abhängigkeit, den die Transaktion für die Daten eingerichtet hat.The lock mode defines the level of dependency the transaction has on the data. Keiner Transaktion wird eine Sperre gewährt, die einen Konflikt mit dem Modus einer Sperre verursachen würde, die einer anderen Transaktion bereits für die betreffenden Daten erteilt wurde.No transaction can be granted a lock that would conflict with the mode of a lock already granted on that data to another transaction. Wenn eine Transaktion einen Sperrmodus anfordert, der einen Konflikt mit einer Sperre verursacht, die bereits für die gleichen Daten erteilt wurde, hält die Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine die anfordernde Transaktion an, bis die erste Sperre freigegeben wird.If a transaction requests a lock mode that conflicts with a lock that has already been granted on the same data, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine will pause the requesting transaction until the first lock is released.

Wenn eine Transaktion Daten ändert, wird die Sperre, die die Änderung schützt, aufrechterhalten, bis die Transaktion abgeschlossen ist.When a transaction modifies a piece of data, it holds the lock protecting the modification until the end of the transaction. Die Zeitdauer der Aufrechterhaltung einer Sperre zum Schutz von Lesevorgängen durch eine Transaktion hängt von der Einstellung für die Isolationsstufe der Transaktion ab.How long a transaction holds the locks acquired to protect read operations depends on the transaction isolation level setting. Alle Sperren, die von einer Transaktion aufrechterhalten werden, werden freigegeben, wenn die Transaktion abgeschlossen ist (d. h. ein Commit oder ein Rollback ausgeführt wurde).All locks held by a transaction are released when the transaction completes (either commits or rolls back).

Anwendungen fordern in der Regel Sperren nicht direkt an.Applications do not typically request locks directly. Sperren werden intern durch eine Komponente von SQL Server-Datenbank-EngineSQL Server Database Engine verwaltet, die als Sperrenmanager bezeichnet wird.Locks are managed internally by a part of the SQL Server-Datenbank-EngineSQL Server Database Engine called the lock manager. Wenn eine Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine eine Transact-SQLTransact-SQL-Anweisung verarbeitet, ermittelt der Abfrageprozessor von SQL Server-Datenbank-EngineSQL Server Database Engine, auf welche Ressourcen zugegriffen werden muss.When an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine processes a Transact-SQLTransact-SQL statement, the SQL Server-Datenbank-EngineSQL Server Database Engine query processor determines which resources are to be accessed. Der Abfrageprozessor ermittelt, welche Arten von Sperren zum Schützen der einzelnen Ressourcen basierend auf dem Zugriffstyp und der Einstellung für den Isolationsgrad der Transaktion erforderlich sind.The query processor determines what types of locks are required to protect each resource based on the type of access and the transaction isolation level setting. Der Abfrageprozessor fordert dann die entsprechenden Sperren vom Sperrenmanager an.The query processor then requests the appropriate locks from the lock manager. Der Sperrenmanager erteilt die Sperren, wenn keine Sperren von anderen Transaktionen aufrechterhalten werden, die einen Konflikt verursachen.The lock manager grants the locks if there are no conflicting locks held by other transactions.

Sperrengranularität und -hierarchienLock Granularity and Hierarchies

Das SQL Server-Datenbank-EngineSQL Server Database Engine verwendet multigranulare Sperren, die das Sperren unterschiedlicher Ressourcentypen durch eine Transaktion ermöglichen.The SQL Server-Datenbank-EngineSQL Server Database Engine has multigranular locking that allows different types of resources to be locked by a transaction. Um die Kosten für das Sperren zu minimieren, sperrt SQL Server-Datenbank-EngineSQL Server Database Engine automatisch Ressourcen auf einer für die Aufgabe geeigneten Stufe.To minimize the cost of locking, the SQL Server-Datenbank-EngineSQL Server Database Engine locks resources automatically at a level appropriate to the task. Bei Verwendung von Sperren mit differenzierterer Granularität, z. B. Sperren für Zeilen, steigt die Parallelität, aber der Verwaltungsaufwand ist größer, da mehr Sperren aufrechterhalten werden müssen, wenn viele Zeilen gesperrt werden.Locking at a smaller granularity, such as rows, increases concurrency but has a higher overhead because more locks must be held if many rows are locked. Die Verwendung von Sperren mit gröberer Granularität, z. B. Sperren für Tabellen, wirkt sich nachteilig auf die Parallelität aus, da durch das Sperren einer gesamten Tabelle der Zugriff auf alle Teile der Tabelle für andere Transaktionen eingeschränkt wird.Locking at a larger granularity, such as tables, are expensive in terms of concurrency because locking an entire table restricts access to any part of the table by other transactions. Der Verwaltungsaufwand nimmt jedoch ab, da weniger Sperren aufrechterhalten werden müssen.However, it has a lower overhead because fewer locks are being maintained.

SQL Server-Datenbank-EngineSQL Server Database Engine muss häufig Sperren auf einer höheren Granularitätsebene einrichten, um eine Ressource vollständig zu schützen.The SQL Server-Datenbank-EngineSQL Server Database Engine often has to acquire locks at multiple levels of granularity to fully protect a resource. Diese Gruppe von Sperren auf mehreren Granularitätsebenen wird als Sperrenhierarchie bezeichnet.This group of locks at multiple levels of granularity is called a lock hierarchy. Um z. B. das Lesen eines Indexes vollständig zu schützen, muss eine Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine gegebenenfalls freigegebene Sperren für Spalten und beabsichtigt-freigegebene Sperren für die Seiten und Tabellen einrichten.For example, to fully protect a read of an index, an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine may have to acquire share locks on rows and intent share locks on the pages and table.

Die folgende Tabelle zeigt die Ressourcen, die SQL Server-Datenbank-EngineSQL Server Database Engine sperren kann.The following table shows the resources that the SQL Server-Datenbank-EngineSQL Server Database Engine can lock.

ResourceResource BESCHREIBUNGDescription
RIDRID Ein Zeilenbezeichner, der verwendet wird, um eine einzelne Zeile in einem Heap zu sperren.A row identifier used to lock a single row within a heap.
KEYKEY Eine Zeilensperre in einem Index, die verwendet wird, um Schlüsselbereiche in serialisierbaren Transaktionen zu schützen.A row lock within an index used to protect key ranges in serializable transactions.
PAGEPAGE Eine 8-KB-Seite in einer Datenbank, z. B. Daten- oder Indexseiten.An 8-kilobyte (KB) page in a database, such as data or index pages.
EXTENTEXTENT Eine zusammenhängende Gruppe von acht Seiten, z. B. Datenseiten oder Indexseiten.A contiguous group of eight pages, such as data or index pages.
HoBTHoBT Ein Heap oder eine B-Struktur.A heap or B-tree. Eine Sperre, die eine B-Struktur (Index) oder den Heap von Datenseiten in einer Tabelle schützt, die keinen gruppierten Index besitzt.A lock protecting a B-tree (index) or the heap data pages in a table that does not have a clustered index.
TABLETABLE Die vollständige Tabelle mit sämtlichen Daten und Indizes.The entire table, including all data and indexes.
FILEFILE Eine Datenbankdatei.A database file.
APPLICATIONAPPLICATION Eine von der Anwendung angegebene Ressource.An application-specified resource.
METADATAMETADATA Metadatensperren.Metadata locks.
ALLOCATION_UNITALLOCATION_UNIT Eine Zuordnungseinheit.An allocation unit.
DATABASEDATABASE Die gesamte Datenbank.The entire database.

Hinweis

HoBT- und TABLE-Sperren können durch die LOCK_ESCALATION-Option von ALTER TABLE beeinflusst werden.HoBT and TABLE locks can be affected by the LOCK_ESCALATION option of ALTER TABLE.

SperrmodiLock Modes

Das SQL Server-Datenbank-EngineSQL Server Database Engine sperrt Ressourcen mithilfe unterschiedlicher Sperrmodi, die bestimmen, wie gleichzeitige Transaktionen auf Ressourcen zugreifen können.The SQL Server-Datenbank-EngineSQL Server Database Engine locks resources using different lock modes that determine how the resources can be accessed by concurrent transactions.

Die folgende Tabelle zeigt die Ressourcen-Sperrmodi, die das SQL Server-Datenbank-EngineSQL Server Database Engine verwendet.The following table shows the resource lock modes that the SQL Server-Datenbank-EngineSQL Server Database Engine uses.

SperrmodusLock mode BESCHREIBUNGDescription
Freigegebene Sperre (Shared, S)Shared (S) Wird für Lesevorgänge verwendet, die Daten nicht ändern oder aktualisieren, wie z. B. SELECT-Anweisungen.Used for read operations that do not change or update data, such as a SELECT statement.
Updatesperre (U)Update (U) Wird für Ressourcen verwendet, die aktualisiert werden können.Used on resources that can be updated. Verhindert eine gängige Form des Deadlocks, die auftritt, wenn mehrere Sitzungen Ressourcen lesen, sperren und anschließend möglicherweise aktualisieren.Prevents a common form of deadlock that occurs when multiple sessions are reading, locking, and potentially updating resources later.
Exklusive Sperre (X)Exclusive (X) Wird bei Datenänderungen wie INSERT-, UPDATE- oder DELETE-Vorgängen verwendet.Used for data-modification operations, such as INSERT, UPDATE, or DELETE. Stellt sicher, dass nicht mehrere Updates an derselben Ressource gleichzeitig vorgenommen werden können.Ensures that multiple updates cannot be made to the same resource at the same time.
AbsichtIntent Wird verwendet, um eine Sperrhierarchie zu erstellen.Used to establish a lock hierarchy. Es gibt folgende Typen von beabsichtigten Sperren: beabsichtigte freigegebene Sperre (Intent Shared, IS), beabsichtigte exklusive Sperre (Intent Exclusive, IX) und freigegebene Sperre mit beabsichtigter exklusiver Sperre (Shared With Intent Exclusive, SIX).The types of intent locks are: intent shared (IS), intent exclusive (IX), and shared with intent exclusive (SIX).
SchemaSchema Wird beim Ausführen von Vorgängen verwendet, die vom Schema einer Tabelle abhängen.Used when an operation dependent on the schema of a table is executing. Es gibt folgende Typen von Schemasperren: Schemaänderungssperre (Sch-M) und Schemastabilitätssperre (Sch-S).The types of schema locks are: schema modification (Sch-M) and schema stability (Sch-S).
Massenaktualisierung (Bulk Update, BU)Bulk Update (BU) Wird beim Massenkopieren von Daten in eine Tabelle verwendet, wenn der TABLOCK-Hinweis angegeben ist.Used when bulk copying data into a table and the TABLOCK hint is specified.
SchlüsselbereichKey-range Schützt den von einer Abfrage gelesenen Zeilenbereich, wenn die serialisierbare Transaktionsisolationsstufe verwendet wird.Protects the range of rows read by a query when using the serializable transaction isolation level. Stellt sicher, dass keine anderen Transaktionen Zeilen einfügen können, die von den Abfragen der serialisierbaren Transaktion berücksichtigt werden können, falls diese erneut ausgeführt würden.Ensures that other transactions cannot insert rows that would qualify for the queries of the serializable transaction if the queries were run again.

Gemeinsame SperrenShared Locks

Freigegebene Sperren (S) ermöglichen, dass Transaktionen eine Ressource gleichzeitig lesen können (SELECT), wenn die Steuerung durch eingeschränkte Parallelität aktiviert ist.Shared (S) locks allow concurrent transactions to read (SELECT) a resource under pessimistic concurrency control. Andere Transaktionen können die Daten nicht ändern, während freigegebene Sperren (S) für die Ressource eingerichtet sind.No other transactions can modify the data while shared (S) locks exist on the resource. Freigegebene Sperren (S) einer Ressource werden aufgehoben, sobald der Lesevorgang abgeschlossen ist, es sei denn, die Isolationsstufe der Transaktion wird auf REPEATABLE READ oder höher festgelegt oder ein Sperrhinweis wird verwendet, um freigegebene Sperren (S) für die Dauer der Transaktion beizubehalten.Shared (S) locks on a resource are released as soon as the read operation completes, unless the transaction isolation level is set to repeatable read or higher, or a locking hint is used to retain the shared (S) locks for the duration of the transaction.

AktualisierungssperrenUpdate Locks

Updatesperren (Update, U) verhindern eine häufige Form von Deadlocks.Update (U) locks prevent a common form of deadlock. Bei REPEATABLE READ- oder SERIALIZABLE-Transaktionen liest die Transaktion Daten, wozu sie eine freigegebene Sperre (S) für die Ressource (Seite oder Zeile) einrichtet, und ändert anschließend die Daten, was eine Konvertierung der Sperre in eine exklusive Sperre (X) erfordert.In a repeatable read or serializable transaction, the transaction reads data, acquiring a shared (S) lock on the resource (page or row), and then modifies the data, which requires lock conversion to an exclusive (X) lock. Wenn zwei Transaktionen eine freigegebene Sperre für eine Ressource einrichten und anschließend versuchen, Daten gleichzeitig zu aktualisieren, versucht die erste Transaktion, die Sperre zu einer exklusiven Sperre (X) zu konvertieren.If two transactions acquire shared-mode locks on a resource and then attempt to update data concurrently, one transaction attempts the lock conversion to an exclusive (X) lock. Diese Konvertierung muss aufgeschoben werden, da der Modus der exklusiven Sperre der einen Transaktion nicht kompatibel mit dem Modus der freigegebenen Sperre der anderen Transaktion ist. Es ergibt sich ein Sperrenwartevorgang.The shared-mode-to-exclusive lock conversion must wait because the exclusive lock for one transaction is not compatible with the shared-mode lock of the other transaction; a lock wait occurs. Die zweite Transaktion versucht nun ebenfalls, eine exklusive Sperre (X) für das Update einzurichten.The second transaction attempts to acquire an exclusive (X) lock for its update. Da beide Transaktionen das Konvertieren in eine exklusive Sperre (X) versuchen und darauf warten, dass die andere Transaktion die freigegebene Sperre aufhebt, kommt es zu einem Deadlock.Because both transactions are converting to exclusive (X) locks, and they are each waiting for the other transaction to release its shared-mode lock, a deadlock occurs.

Um dieses potenzielle Deadlockproblem zu vermeiden, werden Updatesperren (U) verwendet.To avoid this potential deadlock problem, update (U) locks are used. Es kann jeweils nur eine Transaktion eine Updatesperre (U) für eine Ressource einrichten.Only one transaction can obtain an update (U) lock to a resource at a time. Wenn eine Transaktion eine Ressource ändert, wird die Updatesperre (U) in eine exklusive Sperre (X) konvertiert.If a transaction modifies a resource, the update (U) lock is converted to an exclusive (X) lock.

Exklusive SperrenExclusive Locks

Exklusive Sperren (X) verhindern, dass Transaktionen gleichzeitig auf eine Ressource zugreifen.Exclusive (X) locks prevent access to a resource by concurrent transactions. Eine exklusive Sperre (X) bewirkt, dass keine andere Transaktion Daten ändern kann. Lesevorgänge können nur mithilfe des NOLOCK-Hinweises oder der READ UNCOMMITTED-Isolationsstufe ausgeführt werden.With an exclusive (X) lock, no other transactions can modify data; read operations can take place only with the use of the NOLOCK hint or read uncommitted isolation level.

Datenänderungsanweisungen wie INSERT, UPDATE und DELETE setzen sowohl Änderungs- als auch Lesevorgänge voraus.Data modification statements, such as INSERT, UPDATE, and DELETE combine both modification and read operations. Die Anweisung führt zunächst Lesevorgänge aus, um die Daten einzulesen, und anschließend die erforderlichen Änderungsvorgänge.The statement first performs read operations to acquire data before performing the required modification operations. Daher machen Datenänderungsanweisungen normalerweise sowohl freigegebene als auch exklusive Sperren erforderlich.Data modification statements, therefore, typically request both shared locks and exclusive locks. Eine UPDATE-Anweisung kann beispielsweise Zeilen einer Tabelle ändern, die auf einem Join mit einer anderen Tabelle basieren.For example, an UPDATE statement might modify rows in one table based on a join with another table. In diesem Fall fordert die UPDATE-Anweisung freigegebene Sperren für die Zeilen in der verknüpften Tabelle an, sowie exklusive Sperren für die zu aktualisierenden Zeilen.In this case, the UPDATE statement requests shared locks on the rows read in the join table in addition to requesting exclusive locks on the updated rows.

Beabsichtigte SperrenIntent Locks

Das SQL Server-Datenbank-EngineSQL Server Database Engine verwendet beabsichtigte Sperren, um das Platzieren einer freigegebenen (S) oder exklusiven Sperre (X) auf eine Ressource zu schützen, die sich weiter unten in der Sperrhierarchie befinden.The SQL Server-Datenbank-EngineSQL Server Database Engine uses intent locks to protect placing a shared (S) lock or exclusive (X) lock on a resource lower in the lock hierarchy. Die Bezeichnung 'beabsichtige Sperre' bedeutet, dass beabsichtigte Sperren vor Sperren auf untergeordneten Ebenen eingerichtet werden, und damit die Absicht ausdrücken, Sperren auf untergeordneten Ebenen zu platzieren.Intent locks are named intent locks because they are acquired before a lock at the lower level, and therefore signal intent to place locks at a lower level.

Beabsichtigte Sperren werden aus zwei Gründen verwendet:Intent locks serve two purposes:

  • Um zu verhindern, dass andere Transaktionen Ressourcen übergeordneter Ebenen ändern und damit die Sperren untergeordneter Ebenen ungültig werden.To prevent other transactions from modifying the higher-level resource in a way that would invalidate the lock at the lower level.
  • Um die Effizienz des SQL Server-Datenbank-EngineSQL Server Database Engine beim Erkennen von Sperrkonflikten auf einer höheren Granularitätsebene zu steigern.To improve the efficiency of the SQL Server-Datenbank-EngineSQL Server Database Engine in detecting lock conflicts at the higher level of granularity.

Eine beabsichtigte freigegebene Sperre auf Tabellenebene wird also beispielsweise angefordert, bevor freigegebene Sperren (S) für Seiten oder Zeilen in dieser Tabelle angefordert werden.For example, a shared intent lock is requested at the table level before shared (S) locks are requested on pages or rows within that table. Durch Festlegen einer beabsichtigten Sperre auf Tabellenebene wird verhindert, dass andere Transaktionen anschließend eine exklusive Sperre (X) für die Tabelle einrichten können, die diese Seite enthält.Setting an intent lock at the table level prevents another transaction from subsequently acquiring an exclusive (X) lock on the table containing that page. Beabsichtigte Sperren tragen zur Leistungsverbesserung bei, da das SQL Server-Datenbank-EngineSQL Server Database Engine beabsichtige Sperren nur auf Tabellenebene überprüft, um zu bestimmen, ob eine Transaktion für diese Tabelle problemlos eine Sperre einrichten kann.Intent locks improve performance because the SQL Server-Datenbank-EngineSQL Server Database Engine examines intent locks only at the table level to determine if a transaction can safely acquire a lock on that table. Dadurch ist es nicht mehr erforderlich, jede Zeilen- oder Seitensperre in der Tabelle zu überprüfen, um zu ermitteln, ob eine Transaktion die gesamte Tabelle sperren kann.This removes the requirement to examine every row or page lock on the table to determine if a transaction can lock the entire table.

Beabsichtigte Sperren umfassen beabsichtigte freigegebene (Intent Shared, IS), beabsichtigte exklusive (Intent Exclusive, IX) und freigegebene mit beabsichtigten exklusiven (Shared With Intent Exclusive, SIX) Sperren.Intent locks include intent shared (IS), intent exclusive (IX), and shared with intent exclusive (SIX).

SperrmodusLock mode BESCHREIBUNGDescription
Beabsichtigte freigegebene Sperre (Intent Shared, IS)Intent shared (IS) Schützt angeforderte oder eingerichtete freigegebene Sperren bestimmter (aber nicht aller) Ressourcen untergeordneter Ebenen in der Hierarchie.Protects requested or acquired shared locks on some (but not all) resources lower in the hierarchy.
Beabsichtigte exklusive Sperre (Intent Exclusive, IX)Intent exclusive (IX) Schützt angeforderte oder eingerichtete exklusive Sperren bestimmter (aber nicht aller) Ressourcen untergeordneter Ebenen in der Hierarchie.Protects requested or acquired exclusive locks on some (but not all) resources lower in the hierarchy. IX ist eine Obermenge der beabsichtigten freigegebenen Sperre und schützt auch vor Anforderung freigegebener Sperren auf Ressourcen untergeordneter Ebenen in der Hierarchie.IX is a superset of IS, and it also protects requesting shared locks on lower level resources.
Freigegebene Sperre mit beabsichtigter exklusiver Sperre (Shared With Intent Exclusive, SIX)Shared with intent exclusive (SIX) Schützt angeforderte oder eingerichtete freigegebene Sperren aller Ressourcen untergeordneter Ebenen in der Hierarchie sowie beabsichtigte exklusive Sperren bestimmter (aber nicht aller) Ressourcen untergeordneter Ebenen in der Hierarchie.Protects requested or acquired shared locks on all resources lower in the hierarchy and intent exclusive locks on some (but not all) of the lower level resources. Gleichzeitige beabsichtigte freigegebene Sperren auf der Ressource der obersten Ebene sind zugelassen.Concurrent IS locks at the top-level resource are allowed. So werden beispielsweise bei einer Sperre des Typs SIX für eine Tabelle auch beabsichtigte exklusive Sperren für die zu ändernden Seiten sowie exklusive Sperren für die zu ändernden Zeilen eingerichtet.For example, acquiring a SIX lock on a table also acquires intent exclusive locks on the pages being modified and exclusive locks on the modified rows. Es kann jeweils nur eine Sperre des Typs SIX pro Ressource eingerichtet werden, durch die Updates an der Ressource durch andere Transaktionen verhindert werden. Dennoch können andere Transaktionen Ressourcen, die sich weiter unten in der Hierarchie befinden, lesen, indem sie beabsichtigte freigegebene Sperren auf Tabellenebene einrichten.There can be only one SIX lock per resource at one time, preventing updates to the resource made by other transactions, although other transactions can read resources lower in the hierarchy by obtaining IS locks at the table level.
Beabsichtigte Aktualisierungssperre (IU)Intent update (IU) Schützt angeforderte oder eingerichtete Updatesperren aller Ressourcen untergeordneter Hierarchieebenen.Protects requested or acquired update locks on all resources lower in the hierarchy. IU-Sperren werden nur mit Seitenressourcen verwendet.IU locks are used only on page resources. IU-Sperren werden zu IX-Sperren konvertiert, wenn ein Updatevorgang ausgeführt wird.IU locks are converted to IX locks if an update operation takes place.
Gemeinsame Sperre mit beabsichtigter Aktualisierungssperre (SIU)Shared intent update (SIU) Eine Kombination der Sperren vom Typ S und IU, die sich aus der separaten Einrichtung dieser Sperren und dem gleichzeitigen Beibehalten beider Sperren ergibt.A combination of S and IU locks, as a result of acquiring these locks separately and simultaneously holding both locks. Nehmen Sie beispielsweise an, eine Transaktion führt eine Abfrage mit dem PAGLOCK-Hinweis und anschließend einen Updatevorgang aus.For example, a transaction executes a query with the PAGLOCK hint and then executes an update operation. Die Abfrage mit dem PAGLOCK-Hinweis richtet also die S-Sperre ein, wohingegen der Updatevorgang die IU-Sperre einrichtet.The query with the PAGLOCK hint acquires the S lock, and the update operation acquires the IU lock.
Aktualisierungssperre mit beabsichtigter exklusiver Sperre (UIX)Update intent exclusive (UIX) Eine Kombination der Sperren vom Typ U und IX, die sich aus dem separaten Einrichten dieser Sperren und dem gleichzeitigen Beibehalten beider Sperren ergibt.A combination of U and IX locks, as a result of acquiring these locks separately and simultaneously holding both locks.

SchemasperrenSchema Locks

Sperren des Typs Sch-M (Schema Modification, Schemaänderung) werden von SQL Server-Datenbank-EngineSQL Server Database Engine verwendet, wenn für eine Tabelle ein DDL-Vorgang (Data Definition Language, Datendefinitionssprache) ausgeführt wird, wie etwa das Hinzufügen einer Spalte oder Löschen einer Tabelle.The SQL Server-Datenbank-EngineSQL Server Database Engine uses schema modification (Sch-M) locks during a table data definition language (DDL) operation, such as adding a column or dropping a table. Während die Sch-M-Sperre besteht, werden gleichzeitige Zugriffe auf die Tabelle verhindert.During the time that it is held, the Sch-M lock prevents concurrent access to the table. Dies bedeutet, dass die Sch-M-Sperre alle externen Vorgänge blockiert, bis die Sperre aufgehoben wird.This means the Sch-M lock blocks all outside operations until the lock is released.

Einige DML-Vorgänge (Data Manipulation Language), z. B. das Abschneiden von Tabellen, verhindern mithilfe von Sch-M-Sperren, dass gleichzeitige Vorgänge auf die betroffenen Tabellen zugreifen.Some data manipulation language (DML) operations, such as table truncation, use Sch-M locks to prevent access to affected tables by concurrent operations.

SQL Server-Datenbank-EngineSQL Server Database Engine verwendet Sperren des Typs Sch-S (Schemastabilität) beim Kompilieren und Ausführen von Abfragen.The SQL Server-Datenbank-EngineSQL Server Database Engine uses schema stability (Sch-S) locks when compiling and executing queries. Sch-S-Sperren blockieren keine Transaktionssperren, auch keine exklusive Sperren (X).Sch-S locks do not block any transactional locks, including exclusive (X) locks. Daher können während der Kompilierung einer Abfrage andere Transaktionen, einschließlich Transaktionen mit exklusiven Sperren (X) auf Tabellenebene, weiterhin ausgeführt werden.Therefore, other transactions, including those with X locks on a table, continue to run while a query is being compiled. Gleichzeitige DDL-Vorgänge und gleichzeitige DML-Vorgänge, die Sch-M-Sperren abrufen, können für die Tabelle jedoch nicht ausgeführt werden.However, concurrent DDL operations, and concurrent DML operations that acquire Sch-M locks, cannot be performed on the table.

MassenaktualisierungssperrenBulk Update Locks

Massenupdatesperren (BU) werden verwendet, damit mehrere Threads gleichzeitig Daten in dieselbe Tabelle laden können, während sie zugleich anderen Prozessen, die keine Daten massenkopieren, keinen Zugriff auf die Tabelle gewähren.Bulk update (BU) locks allow multiple threads to bulk load data concurrently into the same table while preventing other processes that are not bulk loading data from accessing the table. Das SQL Server-Datenbank-EngineSQL Server Database Engine verwendet Massenupdatesperren (Bulk Update, BU), wenn die folgenden Bedingungen zutreffen.The SQL Server-Datenbank-EngineSQL Server Database Engine uses bulk update (BU) locks when both of the following conditions are true.

  • Zum Massenkopieren von Daten in eine Tabelle verwenden Sie die Transact-SQLTransact-SQL-Anweisung BULK INSERT oder die OPENROWSET(BULK)-Funktion. Sie können auch einen der Masseneinfügungs-API-Befehle wie „.NET SqlBulkCopy“, OLEDB-FastLoad-APIs oder die ODBC-APIs für das Massenkopieren verwenden.You use the Transact-SQLTransact-SQL BULK INSERT statement, or the OPENROWSET(BULK) function, or you use one of the Bulk Insert API commands such as .NET SqlBulkCopy, OLEDB Fast Load APIs, or the ODBC Bulk Copy APIs to bulk copy data into a table.
  • Es wird entweder der TABLOCK-Hinweis angegeben oder die Tabellenoption table lock on bulk load mithilfe von sp_tableoption festgelegt.The TABLOCK hint is specified or the table lock on bulk load table option is set using sp_tableoption.

Tipp

Im Gegensatz zur BULK INSERT-Anweisung, die eine weniger restriktive Massenupdatesperre enthält, weist INSERT INTO…SELECT mit dem TABLOCK-Hinweis eine exklusive Sperre (X) für die Tabelle auf.Unlike the BULK INSERT statement, which holds a less restrictive Bulk Update lock, INSERT INTO...SELECT with the TABLOCK hint holds an exclusive (X) lock on the table. Das bedeutet, dass Sie keine Zeilen mit parallelen Einfügevorgängen einfügen können.This means that you cannot insert rows using parallel insert operations.

SchlüsselbereichssperrenKey-Range Locks

Schlüsselbereichssperren schützen einen Bereich von Zeilen, die implizit in ein Recordset eingeschlossen wurden, das von einer Transact-SQLTransact-SQL-Anweisung gelesen wird; dies geschieht bei Verwendung der Transaktionsisolationsstufe SERIALIZABLE.Key-range locks protect a range of rows implicitly included in a record set being read by a Transact-SQLTransact-SQL statement while using the serializable transaction isolation level. Durch Schlüsselbereichssperren werden Phantomlesezugriffe verhindert.Key-range locking prevents phantom reads. Indem die Schlüsselbereiche zwischen Zeilen geschützt werden, wird auch verhindert, dass beim Zugreifen von Transaktionen auf Recordsets Phantomeinfügungen oder -löschungen erfolgen.By protecting the ranges of keys between rows, it also prevents phantom insertions or deletions into a record set accessed by a transaction.

Kompatibilität von SperrenLock Compatibility

Durch die Kompatibilität von Sperren wird gesteuert, ob mehrere Transaktionen gleichzeitig Sperren für dieselbe Ressource einrichten können.Lock compatibility controls whether multiple transactions can acquire locks on the same resource at the same time. Wenn eine Ressource bereits durch eine andere Transaktion gesperrt wurde, kann eine erneute Sperranforderung nur gewährt werden, wenn der Modus der angeforderten Sperre mit dem Modus der vorhandenen Sperre kompatibel ist.If a resource is already locked by another transaction, a new lock request can be granted only if the mode of the requested lock is compatible with the mode of the existing lock. Wenn der Modus der angeforderten Sperre nicht mit dem Modus der vorhandenen Sperre kompatibel ist, wartet die Transaktion, von der die neue Sperre angefordert wird, bis die vorhandene Sperre aufgehoben wird oder bis das Timeoutintervall der Sperre abgelaufen ist.If the mode of the requested lock is not compatible with the existing lock, the transaction requesting the new lock waits for the existing lock to be released or for the lock timeout interval to expire. So sind z. B. keine anderen Sperrmodi mit exklusiven Sperren kompatibel.For example, no lock modes are compatible with exclusive locks. Wenn eine exklusive Sperre (X) eingerichtet ist, kann eine andere Transaktion eine Sperre jeglicher Art (freigegeben, Update oder exklusiv) für die Ressource erst dann einrichten, wenn die exklusive Sperre (X) am Ende der ersten Transaktion aufgehoben wird.While an exclusive (X) lock is held, no other transaction can acquire a lock of any kind (shared, update, or exclusive) on that resource until the exclusive (X) lock is released. Falls hingegen eine freigegebene Sperre (Shared, S) auf eine Ressource angewendet wurde, können andere Transaktionen ebenfalls eine freigegebene Sperre oder eine Updatesperre (Update, U) auf dieses Element anwenden, selbst wenn die erste Transaktion noch nicht beendet ist.Alternatively, if a shared (S) lock has been applied to a resource, other transactions can also acquire a shared lock or an update (U) lock on that item even if the first transaction has not completed. Andere Transaktionen können jedoch eine exklusive Sperre erst dann einrichten, wenn die freigegebene Sperre aufgehoben wurde.However, other transactions cannot acquire an exclusive lock until the shared lock has been released.

Die folgende Tabelle stellt die Kompatibilität der am häufigsten auftretenden Sperrmodi dar.The following table shows the compatibility of the most commonly encountered lock modes.

Vorhandener erteilter ModusExisting granted mode
Angeforderter ModusRequested mode ISIS SS UU IXIX SIXSIX XX
Beabsichtigte freigegebene Sperre (Intent Shared, IS)Intent shared (IS) JaYes JaYes JaYes JaYes JaYes NeinNo
Freigegebene Sperre (Shared, S)Shared (S) JaYes JaYes JaYes NeinNo NeinNo NeinNo
Updatesperre (U)Update (U) JaYes JaYes NeinNo NeinNo NeinNo NeinNo
Beabsichtigte exklusive Sperre (Intent Exclusive, IX)Intent exclusive (IX) JaYes NeinNo NeinNo JaYes NeinNo NeinNo
Freigegebene Sperre mit beabsichtigter exklusiver Sperre (Shared With Intent Exclusive, SIX)Shared with intent exclusive (SIX) JaYes NeinNo NeinNo NeinNo NeinNo NeinNo
Exklusive Sperre (X)Exclusive (X) NeinNo NeinNo NeinNo NeinNo NeinNo NeinNo

Hinweis

Eine beabsichtigte exklusive Sperre (IX) ist mit einem Sperrmodus des Typs IX kompatibel, da IX nur die Absicht zum Aktualisieren einiger statt aller Zeilen anzeigt.An intent exclusive (IX) lock is compatible with an IX lock mode because IX means the intention is to update only some of the rows rather than all of them. Andere Transaktionen, die versuchen, einige der Zeilen zu lesen oder zu aktualisieren, werden ebenfalls zugelassen, sofern es sich nicht um dieselben Zeilen handelt, die von anderen Transaktionen aktualisiert werden.Other transactions that attempt to read or update some of the rows are also permitted as long as they are not the same rows being updated by other transactions. Wenn zwei Transaktionen versuchen, dieselbe Zeile zu aktualisieren, wird beiden Transaktionen eine IX-Sperre auf Tabellen- und Seitenebene erteilt.Further, if two transactions attempt to update the same row, both transactions will be granted an IX lock at table and page level. Bei nur einer Transaktion wird jedoch eine X-Sperre auf Zeilenebene erteilt.However, one transaction will be granted an X lock at row level. Die andere Transaktion muss warten, bis die Sperre auf Zeilenebene aufgehoben wird.The other transaction must wait until the row-level lock is removed.

Verwenden Sie die folgende Tabelle, um die Kompatibilität aller in SQL ServerSQL Server verfügbaren Sperrmodi zu ermitteln.Use the following table to determine the compatibility of all the lock modes available in SQL ServerSQL Server.

lock_conflicts

SchlüsselbereichssperrenKey-Range Locking

Schlüsselbereichssperren schützen einen Bereich von Zeilen, die implizit in ein Recordset eingeschlossen wurden, das von einer Transact-SQLTransact-SQL-Anweisung gelesen wird; dies geschieht bei Verwendung der Transaktionsisolationsstufe SERIALIZABLE.Key-range locks protect a range of rows implicitly included in a record set being read by a Transact-SQLTransact-SQL statement while using the serializable transaction isolation level. Für die Isolationsstufe SERIALIZABLE muss jede Abfrage, die während einer Transaktion ausgeführt wird, dieselben Zeilen erhalten, wenn sie im Rahmen der Transaktion ausgeführt wird.The serializable isolation level requires that any query executed during a transaction must obtain the same set of rows every time it is executed during the transaction. Durch eine Schlüsselbereichssperre wird diese Anforderung geschützt, indem verhindert wird, dass von anderen Transaktionen neue Zeilen eingefügt werden, deren Schlüssel dem Schlüsselbereich zugehörig sind, die von der serialisierbaren Transaktion gelesen werden.A key range lock protects this requirement by preventing other transactions from inserting new rows whose keys would fall in the range of keys read by the serializable transaction.

Durch Schlüsselbereichssperren werden Phantomlesezugriffe verhindert.Key-range locking prevents phantom reads. Indem die Schlüsselbereiche zwischen Zeilen geschützt werden, wird außerdem verhindert, dass es zu Phantomeinfügungsvorgängen in Datensätzen kommt, auf die eine Transaktion zugreift.By protecting the ranges of keys between rows, it also prevents phantom insertions into a set of records accessed by a transaction.

Eine Schlüsselbereichssperre wird für einen Index platziert; auf diese Weise wird ein Start- und Endschlüsselwert angegeben.A key-range lock is placed on an index, specifying a beginning and ending key value. Durch diese Sperre wird jeglicher Versuch blockiert, eine Zeile mit einem Schlüsselwert einzufügen, zu aktualisieren oder zu löschen, der dem Bereich zugehörig ist, da von diesen Vorgängen zunächst eine Sperre für den Index eingerichtet werden müsste.This lock blocks any attempt to insert, update, or delete any row with a key value that falls in the range because those operations would first have to acquire a lock on the index. Eine serialisierbare Transaktion könnte beispielsweise eine SELECT-Anweisung ausgeben, die alle Zeilen liest, deren Schlüsselwerte mit der Bedingung BETWEEN 'AAA' AND 'CZZ' übereinstimmen.For example, a serializable transaction could issue a SELECT statement that reads all rows whose key values match the condition BETWEEN 'AAA' AND 'CZZ'. Eine Schlüsselbereichssperre für die Schlüsselwerte im Bereich von ' AAA ' bis ' CZZ ' verhindert, dass andere Transaktionen Zeilen mit Schlüsselwerten in diesem Bereich einfügen, beispielsweise ' ADG ' , ' BBD ' oder ' CAL ' .A key-range lock on the key values in the range from ' AAA ' to ' CZZ ' prevents other transactions from inserting rows with key values anywhere in that range, such as ' ADG ', ' BBD ', or ' CAL '.

Sperrmodi für SchlüsselbereicheKey-Range Lock Modes

Zu Schlüsselbereichssperren gehören eine Bereichs- und eine Zeilenkomponente, die im Bereichszeilenformat angegeben werden.Key-range locks include both a range and a row component specified in range-row format:

  • Bereich stellt den Sperrmodus dar, der den Bereich zwischen zwei aufeinander folgenden Indexeinträgen schützt.Range represents the lock mode protecting the range between two consecutive index entries.

  • Zeile stellt den Sperrmodus dar, der den Indexeintrag schützt.Row represents the lock mode protecting the index entry.

  • Modus stellt den kombinierten Sperrmodus dar, der verwendet wird.Mode represents the combined lock mode used. Schlüsselbereichssperrmodi setzen sich aus zwei Teilen zusammen.Key-range lock modes consist of two parts. Der erste gibt den Sperrtyp wieder, der zum Sperren des Indexbereichs (RangeT) verwendet wird, und der zweite gibt den Sperrtyp wieder, der zum Sperren eines bestimmten Schlüssels (K) verwendet wird.The first represents the type of lock used to lock the index range (RangeT) and the second represents the lock type used to lock a specific key (K). Die beiden Teile sind durch einen Bindestrich (-) miteinander verbunden, beispielsweise RangeT-K.The two parts are connected with a hyphen (-), such as RangeT-K.

    RangeRange ZeileRow ModeMode BESCHREIBUNGDescription
    RangeSRangeS ES RangeS-SRangeS-S Freigegebene Bereichssperre, freigegebene Ressourcensperre; serialisierbarer Bereichsscan.Shared range, shared resource lock; serializable range scan.
    RangeSRangeS UU RangeS-URangeS-U Freigegebene Sperre für Bereich und Updatesperre für Ressource; serialisierbarer Updatescan.Shared range, update resource lock; serializable update scan.
    RangeIRangeI NullNull RangeI-NRangeI-N Einfügungssperre für Bereich und NULL-Sperre für Ressource; wird verwendet, um Bereiche vor dem Einfügen eines neuen Schlüssels in einen Index zu testen.Insert range, null resource lock; used to test ranges before inserting a new key into an index.
    RangeXRangeX XX RangeX-XRangeX-X Exklusive Sperren für Bereich und Ressource; wird beim Aktualisieren eines Schlüssels in einem Bereich verwendet.Exclusive range, exclusive resource lock; used when updating a key in a range.

Hinweis

Der interne NULL-Sperrmodus ist mit allen anderen Sperrmodi kompatibel.The internal Null lock mode is compatible with all other lock modes.

Schlüsselbereichssperrmodi haben eine Kompatibilitätsmatrix, die zeigt, welche Sperren mit anderen Sperren, die für überlappende Schlüssel und Bereiche eingerichtet wurden, kompatibel sind.Key-range lock modes have a compatibility matrix that shows which locks are compatible with other locks obtained on overlapping keys and ranges.

Vorhandener erteilter ModusExisting granted mode
Angeforderter ModusRequested mode SS UU XX RangeS-SRangeS-S RangeS-URangeS-U RangeI-NRangeI-N RangeX-XRangeX-X
Freigegebene Sperre (Shared, S)Shared (S) JaYes JaYes NeinNo JaYes JaYes JaYes NeinNo
Updatesperre (U)Update (U) JaYes NeinNo NeinNo JaYes NeinNo JaYes NeinNo
Exklusive Sperre (X)Exclusive (X) NeinNo NeinNo NeinNo NeinNo NeinNo JaYes NeinNo
RangeS-SRangeS-S JaYes JaYes NeinNo JaYes JaYes NeinNo NeinNo
RangeS-URangeS-U JaYes NeinNo NeinNo JaYes NeinNo NeinNo NeinNo
RangeI-NRangeI-N JaYes JaYes JaYes NeinNo NeinNo JaYes NeinNo
RangeX-XRangeX-X NeinNo NeinNo NeinNo NeinNo NeinNo NeinNo NeinNo

KonvertierungssperrenConversion Locks

Konvertierungssperren werden erstellt, wenn eine Schlüsselbereichssperre eine andere Sperre überlappt.Conversion locks are created when a key-range lock overlaps another lock.

Sperre 1Lock 1 Sperre 2Lock 2 KonvertierungssperreConversion lock
ES RangeI-NRangeI-N RangeI-SRangeI-S
UU RangeI-NRangeI-N RangeI-URangeI-U
XX RangeI-NRangeI-N RangeI-XRangeI-X
RangeI-NRangeI-N RangeS-SRangeS-S RangeX-SRangeX-S
RangeI-NRangeI-N RangeS-URangeS-U RangeX-URangeX-U

Konvertierungssperren lassen sich für eine kurze Zeitdauer unter verschiedenen komplexen Bedingungen beobachten, so gelegentlich bei der Ausführung gleichzeitiger Prozesse.Conversion locks can be observed for a short period of time under different complex circumstances, sometimes while running concurrent processes.

Serialisierbarer Bereichsscan, Singleton-Abruf, Löschen und EinfügenSerializable Range Scan, Singleton Fetch, Delete, and Insert

Durch Schlüsselbereichssperren wird sichergestellt, dass folgende Vorgänge serialisierbar sind:Key-range locking ensures that the following operations are serializable:

  • BereichsscanabfrageRange scan query
  • Singleton-Abruf einer nicht vorhandenen ZeileSingleton fetch of nonexistent row
  • LöschvorgangDelete operation
  • EinfügungsvorgangInsert operation

Folgende Bedingungen müssen erfüllt werden, ehe Schlüsselbereichssperren verwendet werden können:Before key-range locking can occur, the following conditions must be satisfied:

  • Die Isolationsstufe der Transaktion muss auf SERIALIZABLE festgelegt sein.The transaction-isolation level must be set to SERIALIZABLE.
  • Der Abfrageprozessor muss zum Implementieren des Bereichsfilterprädikäts verwendet werden.The query processor must use an index to implement the range filter predicate. Beispiel: Die WHERE-Klausel in einer SELECT-Anweisung könnte eine Bereichsbedingung mit diesem Prädikat erstellen: ColumnX BETWEEN N ' AAA ' AND N ' CZZ ' .For example, the WHERE clause in a SELECT statement could establish a range condition with this predicate: ColumnX BETWEEN N ' AAA ' AND N ' CZZ '. Eine Schlüsselbereichssperre kann nur eingerichtet werden, wenn ColumnX durch einen Indexschlüssel abgedeckt ist.A key-range lock can only be acquired if ColumnX is covered by an index key.

BeispieleExamples

Die nachfolgende Tabelle und der nachfolgende Index dienen als Grundlage für die Beispiele für Schlüsselbereichssperren, die nachfolgend aufgeführt sind.The following table and index are used as a basis for the key-range locking examples that follow.

B-Struktur

BereichsscanabfrageRange Scan Query

Um sicherzustellen, dass eine Bereichsscanabfrage serialisierbar ist, sollte dieselbe Abfrage immer dieselben Ergebnisse zurückgeben, wenn sie innerhalb derselben Transaktion ausgeführt wird.To ensure a range scan query is serializable, the same query should return the same results each time it is executed within the same transaction. Neue Zeilen dürfen innerhalb der Bereichsscanabfrage nicht von anderen Transaktionen eingefügt werden, da diese sonst zu Phantomeinfügungen werden.New rows must not be inserted within the range scan query by other transactions; otherwise, these become phantom inserts. In der nachfolgenden Abfrage werden beispielsweise die Tabelle und der Index in der obigen Abbildung verwendet:For example, the following query uses the table and index in the previous illustration:

SELECT name  
FROM mytable  
WHERE name BETWEEN 'A' AND 'C';  

Es werden Schlüsselbereichssperren auf die Indexeinträge angewendet, die dem Datenzeilenbereich entsprechen, in dem der Name zwischen den Werten Adam und Dale liegt. Dadurch wird verhindert, dass neue Zeilen, die der vorhergehenden Abfrage entsprechen, hinzugefügt oder gelöscht werden.Key-range locks are placed on the index entries corresponding to the range of data rows where the name is between the values Adam and Dale, preventing new rows qualifying in the previous query from being added or deleted. Obwohl Adam der erste Name in diesem Bereich ist, wird durch die Schlüsselbereichssperre mit dem Modus RangeS-S für diesen Indexeintrag sichergestellt, dass keine neuen Namen mit dem Anfangsbuchstaben A vor dem Namen Adam eingefügt werden können, beispielsweise Abigail.Although the first name in this range is Adam, the RangeS-S mode key-range lock on this index entry ensures that no new names beginning with the letter A can be added before Adam, such as Abigail. Entsprechend wird durch die Schlüsselbereichssperre mit dem Modus RangeS-S für den Indexeintrag für Dale sichergestellt, dass keine neuen Namen mit dem Anfangsbuchstaben C nach dem Namen Carlos eingefügt werden können, beispielsweise Clive.Similarly, the RangeS-S key-range lock on the index entry for Dale ensures that no new names beginning with the letter C can be added after Carlos, such as Clive.

Hinweis

Die Anzahl der aufrechterhaltenen Sperren vom Typ „RangeS-S“ entspricht n+1. Hierbei ist n die Anzahl der Zeilen, die der Abfrage entsprechen.The number of RangeS-S locks held is n+1, where n is the number of rows that satisfy the query.

Singleton-Abruf nicht vorhandener DatenSingleton Fetch of Nonexistent Data

Wenn eine Abfrage in einer Transaktion versucht, eine nicht vorhandene Zeile auszuwählen, muss die Abfrage, wenn sie zu einem späteren Zeitpunkt innerhalb derselben Transaktion erneut ausgegeben wird, zu demselben Ergebnis führen.If a query within a transaction attempts to select a row that does not exist, issuing the query at a later point within the same transaction has to return the same result. Es darf für keine andere Transaktion zulässig sein, diese nicht vorhandene Zeile einzufügen.No other transaction can be allowed to insert that nonexistent row. Angenommen, die folgende Abfrage wird ausgeführt:For example, given this query:

SELECT name  
FROM mytable  
WHERE name = 'Bill';  

Es wird eine Schlüsselbereichssperre für den Indexeintrag platziert, der dem Namensbereich von Ben bis Bing entspricht, da der Name Bill zwischen den beiden aufeinander folgenden Indexeinträgen eingefügt würde.A key-range lock is placed on the index entry corresponding to the name range from Ben to Bing because the name Bill would be inserted between these two adjacent index entries. Die Schlüsselbereichssperre mit dem Modus RangeS-S wird für den Indexeintrag Bing platziert.The RangeS-S mode key-range lock is placed on the index entry Bing. Dadurch wird verhindert, dass andere Transaktionen Werte, wie etwa Bill, zwischen die Indexeinträge Ben und Bing einfügen.This prevents any other transaction from inserting values, such as Bill, between the index entries Ben and Bing.

LöschvorgangDelete Operation

Wenn ein Wert in einer Transaktion gelöscht wird, muss der Bereich, in dem der Wert liegt, nicht für die gesamte Dauer der Transaktion, die den Löschvorgang ausführt, gesperrt werden.When deleting a value within a transaction, the range the value falls into does not have to be locked for the duration of the transaction performing the delete operation. Die Serialisierbarkeit wird bereits dann aufrechterhalten, wenn der gelöschte Schlüsselwert bis zum Ende der Transaktion gesperrt wird.Locking the deleted key value until the end of the transaction is sufficient to maintain serializability. Angenommen, folgende DELETE-Anweisung wird ausgeführt:For example, given this DELETE statement:

DELETE mytable  
WHERE name = 'Bob';  

Eine exklusive Sperre (X) wird für den Indexeintrag platziert, der dem Namen Bob entspricht.An exclusive (X) lock is placed on the index entry corresponding to the name Bob. Andere Transaktionen können Werte vor oder nach dem gelöschten Wert Bob einfügen oder löschen.Other transactions can insert or delete values before or after the deleted value Bob. Eine Transaktion, die versucht, den Wert Bob zu lesen, einzufügen oder zu löschen, wird jedoch so lange blockiert, bis für die löschende Transaktion entweder ein Commit oder ein Rollback ausgeführt wird.However, any transaction that attempts to read, insert, or delete the value Bob will be blocked until the deleting transaction either commits or rolls back.

Das Löschen des Bereichs kann mithilfe von drei grundlegenden Sperrmodi ausgeführt werden: Zeilen-, Seiten- oder Tabellensperre.Range delete can be executed using three basic lock modes: row, page, or table lock. Die Verwendung der Zeilen-, Seiten- oder Tabellensperren wird vom Abfrageoptimierer festgelegt oder kann vom Benutzer über Optimierungshinweise, wie ROWLOCK, PAGLOCK oder TABLOCK, angegeben werden.The row, page, or table locking strategy is decided by query optimizer or can be specified by the user through optimizer hints such as ROWLOCK, PAGLOCK, or TABLOCK. Wenn PAGLOCK oder TABLOCK verwendet wird, hebt SQL Server-Datenbank-EngineSQL Server Database Engine umgehend die Zuordnung einer Indexseite auf, wenn sämtliche Zeilen dieser Seite gelöscht werden.When PAGLOCK or TABLOCK is used, the SQL Server-Datenbank-EngineSQL Server Database Engine immediately deallocates an index page if all rows are deleted from this page. Wenn hingegen ROWLOCK verwendet wird, werden sämtliche Zeilen lediglich als gelöscht markiert und zu einem späteren Zeitpunkt mithilfe eines Hintergrundtasks von der Indexseite entfernt.In contrast, when ROWLOCK is used, all deleted rows are marked only as deleted; they are removed from the index page later using a background task.

EinfügungsvorgangInsert Operation

Wenn ein Wert in einer Transaktion eingefügt wird, muss der Bereich, in dem der Wert liegt, nicht für die gesamte Dauer der Transaktion, die den Einfügungsvorgang ausführt, gesperrt werden.When inserting a value within a transaction, the range the value falls into does not have to be locked for the duration of the transaction performing the insert operation. Die Serialisierbarkeit wird bereits dann aufrechterhalten, wenn der eingefügte Schlüsselwert bis zum Ende der Transaktion gesperrt wird.Locking the inserted key value until the end of the transaction is sufficient to maintain serializability. Angenommen, folgende INSERT-Anweisung wird ausgeführt:For example, given this INSERT statement:

INSERT mytable VALUES ('Dan');  

Für den Indexeintrag, der dem Namen David entspricht, wird die Schlüsselbereichssperre mit dem Modus RangeI-N platziert, um den Bereich zu testen.The RangeI-N mode key-range lock is placed on the index entry corresponding to the name David to test the range. Wenn die Sperre erteilt wird, wird Dan eingefügt, und für den Wert Dan wird eine exklusive Sperre (X) platziert.If the lock is granted, Dan is inserted and an exclusive (X) lock is placed on the value Dan. Die Schlüsselbereichssperre mit dem Modus RangeI-N ist nur notwendig, um den Bereich zu testen, und wird nicht für die Dauer der Transaktion aufrechterhalten, die den Einfügungsvorgang ausführt.The RangeI-N mode key-range lock is necessary only to test the range and is not held for the duration of the transaction performing the insert operation. Andere Transaktionen können Werte vor oder nach dem eingefügten Wert Dan einfügen oder löschen.Other transactions can insert or delete values before or after the inserted value Dan. Eine Transaktion, die versucht, den Wert Dan zu lesen, einzufügen oder zu löschen, wird jedoch so lange gesperrt, bis für die einfügende Transaktion entweder ein Commit oder ein Rollback ausgeführt wird.However, any transaction attempting to read, insert, or delete the value Dan will be locked until the inserting transaction either commits or rolls back.

Dynamische SperreDynamic Locking

Wenn Sie Sperren auf niedriger Ebene verwenden, z. B. Zeilensperren, wird die Parallelität erhöht, da die Wahrscheinlichkeit geringer ist, dass zwei Transaktionen gleichzeitig Sperren für die gleichen Daten anfordern.Using low-level locks, such as row locks, increases concurrency by decreasing the probability that two transactions will request locks on the same piece of data at the same time. Das Verwenden von Sperren auf niedriger Ebene erhöht außerdem die Anzahl der Sperren sowie der Ressourcen, die für deren Verwaltung erforderlich sind.Using low-level locks also increases the number of locks and the resources needed to manage them. Wenn Sie Tabellen- oder Seitensperren auf hoher Ebene verwenden, wird der Aufwand zwar gesenkt, jedoch auf Kosten der Parallelität.Using high-level table or page locks lowers overhead, but at the expense of lowering concurrency.

lockcht

SQL Server-Datenbank-EngineSQL Server Database Engine legt Sperren dynamisch fest, um die kosteneffektivsten Sperren zu bestimmen.The SQL Server-Datenbank-EngineSQL Server Database Engine uses a dynamic locking strategy to determine the most cost-effective locks. SQL Server-Datenbank-EngineSQL Server Database Engine bestimmt beim Ausführen einer Abfrage automatisch, welche Sperren, basierend auf den Merkmalen des Schemas und der Abfrage, am sinnvollsten sind.The SQL Server-Datenbank-EngineSQL Server Database Engine automatically determines what locks are most appropriate when the query is executed, based on the characteristics of the schema and query. Um beispielsweise den Aufwand für die Sperren zu senken, kann der Abfrageoptimierer festlegen, dass beim Ausführen eines Indexscans Sperren auf Seitenebene für einen Index eingerichtet werden.For example, to reduce the overhead of locking, the optimizer may choose page-level locks in an index when performing an index scan.

Dynamische Sperren bieten die folgenden Vorteile:Dynamic locking has the following advantages:

  • Vereinfachte Datenbankverwaltung.Simplified database administration. Datenbankadministratoren müssen die Sperreneskalationsschwellen nicht anpassen.Database administrators do not have to adjust lock escalation thresholds.
  • Gesteigerte Leistung.Increased performance. SQL Server-Datenbank-EngineSQL Server Database Engine minimiert den Aufwand des Systems mithilfe von Sperren, die speziell auf die Aufgabe zugeschnitten sind.The SQL Server-Datenbank-EngineSQL Server Database Engine minimizes system overhead by using locks appropriate to the task.
  • Anwendungsentwickler können sich auf die Entwicklung konzentrieren.Application developers can concentrate on development. SQL Server-Datenbank-EngineSQL Server Database Engine passt Sperren automatisch an.The SQL Server-Datenbank-EngineSQL Server Database Engine adjusts locking automatically.

In SQL Server 2008SQL Server 2008 und höheren Versionen hat sich das Verhalten der Sperrenausweitung mit der Einführung der LOCK_ESCALATION-Option geändert.Starting with SQL Server 2008SQL Server 2008, the behavior of lock escalation has changed with the introduction of the LOCK_ESCALATION option. Weitere Informationen finden Sie unter der LOCK_ESCALATION-Option von ALTER TABLE.For more information, see the LOCK_ESCALATION option of ALTER TABLE.

DeadlocksDeadlocks

Ein Deadlock tritt auf, wenn zwei Tasks einander dauerhaft gegenseitig blockieren, weil jeder der Tasks eine Sperre für eine Ressource aufrecht erhält, die die anderen Tasks zu sperren versuchen.A deadlock occurs when two or more tasks permanently block each other by each task having a lock on a resource which the other tasks are trying to lock. Beispiel:For example:

  • Die Transaktion A richtet eine freigegebene Sperre für Zeile 1 ein.Transaction A acquires a share lock on row 1.
  • Die Transaktion B richtet eine freigegebene Sperre für Zeile 2 ein.Transaction B acquires a share lock on row 2.
  • Die Transaktion A fordert nun eine exklusive Sperre für Zeile 2 an und ist blockiert, bis die Transaktion B beendet ist und die freigegebene Sperre für Zeile 2 aufhebt.Transaction A now requests an exclusive lock on row 2, and is blocked until transaction B finishes and releases the share lock it has on row 2.
  • Die Transaktion B fordert nun eine exklusive Sperre für Zeile 1 an und ist blockiert, bis die Transaktion A beendet ist und die freigegebene Sperre für Zeile 1 aufhebt.Transaction B now requests an exclusive lock on row 1, and is blocked until transaction A finishes and releases the share lock it has on row 1.

Transaktion A kann erst nach Ende von Transaktion B ausgeführt werden, aber Transaktion B ist durch Transaktion A blockiert. Diese Bedingung wird auch als zyklische Abhängigkeit bezeichnet. Transaktion A hängt von Transaktion B ab, und Transaktion B schließt den Kreis, da sie von Transaktion A abhängt.Transaction A cannot complete until transaction B completes, but transaction B is blocked by transaction A. This condition is also called a cyclic dependency: Transaction A has a dependency on transaction B, and transaction B closes the circle by having a dependency on transaction A.

Die beiden Transaktionen, die sich im Deadlock befinden, werden auf unbegrenzte Zeit aufeinander warten, es sei denn, der Deadlock wird von einem externen Prozess unterbrochen.Both transactions in a deadlock will wait forever unless the deadlock is broken by an external process. Der SQL Server-Datenbank-EngineSQL Server Database Engine-Deadlockmonitor überprüft regelmäßig, ob sich Tasks in einem Deadlock befinden.The SQL Server-Datenbank-EngineSQL Server Database Engine deadlock monitor periodically checks for tasks that are in a deadlock. Wenn der Monitor eine solche zyklische Abhängigkeit erkennt, wählt er einen der Tasks als Opfer aus und beendet dessen Transaktion mit einem Fehler.If the monitor detects a cyclic dependency, it chooses one of the tasks as a victim and terminates its transaction with an error. Dies ermöglicht dem anderen Task, seine Transaktion abzuschließen.This allows the other task to complete its transaction. Die Anwendung mit der Transaktion, die mit einem Fehler beendet wurde, kann nun erneut versuchen, die Transaktion auszuführen. Dies gelingt nun normalerweise, nachdem die andere, an dem Deadlock beteiligte Transaktion bereits abgeschlossen ist.The application with the transaction that terminated with an error can retry the transaction, which usually completes after the other deadlocked transaction has finished.

Deadlocks werden oft mit normalen Blockierungen verwechselt.Deadlocking is often confused with normal blocking. Wenn eine Transaktion eine Sperre für eine Ressource anfordert, die bereits von einer anderen Transaktion gesperrt ist, wartet die anfordernde Transaktion, bis die Sperre aufgehoben wird.When a transaction requests a lock on a resource locked by another transaction, the requesting transaction waits until the lock is released. Standardmäßig treten bei SQL ServerSQL Server-Transaktionen keine Timeouts auf, es sei denn, LOCK_TIMEOUT wurde festgelegt.By default, SQL ServerSQL Server transactions do not time out, unless LOCK_TIMEOUT is set. Die anfordernde Transaktion ist also blockiert, befindet sich aber nicht in einem Deadlock, da sie ihrerseits die andere Transaktion, die im Besitz der Sperre ist, nicht blockiert.The requesting transaction is blocked, not deadlocked, because the requesting transaction has not done anything to block the transaction owning the lock. Die Transaktion, die die Sperre besitzt, wird zu gegebener Zeit abgeschlossen und die Sperre aufgehoben, woraufhin die anfordernde Transaktion die Sperre erhält und den Transaktionsvorgang ausführt.Eventually, the owning transaction will complete and release the lock, and then the requesting transaction will be granted the lock and proceed.

Hinweis

Deadlocks werden manchmal auch "deadly embrace" (tödliche Umarmung) genannt.Deadlocks are sometimes called a deadly embrace.

Ein Deadlock ist eine Bedingung, die in jedem System mit mehreren Threads auftreten kann, nicht nur bei Managementsystemen für relationale Datenbanken, sowie in anderen Ressourcen als Sperren für Datenbankobjekte.Deadlock is a condition that can occur on any system with multiple threads, not just on a relational database management system, and can occur for resources other than locks on database objects. Ein Thread in einem Multithread-Betriebssystem kann beispielsweise eine Ressource oder mehrere Ressourcen, wie z. B. Speicherblöcke, reservieren.For example, a thread in a multithreaded operating system might acquire one or more resources, such as blocks of memory. Wenn sich die zu reservierende Ressource derzeit im Besitz eines anderen Threads befindet, muss der erste Thread eventuell warten, bis der Besitzerthread die Zielressource freigegeben hat.If the resource being acquired is currently owned by another thread, the first thread may have to wait for the owning thread to release the target resource. Der wartende Thread ist für diese bestimmte Ressource abhängig vom Besitzerthread.The waiting thread is said to have a dependency on the owning thread for that particular resource. In einer Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine können Sitzungen beim Reservieren von anderen als Datenbankressourcen, wie z. B. Speicher oder Threads, in eine Deadlocksituation geraten.In an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine, sessions can deadlock when acquiring nondatabase resources, such as memory or threads.

Diagramm mit Transaktionsdeadlock

In der Abbildung weist Transaktion T1 eine Abhängigkeit von Transaktion T2 für die Sperrressource der Part-Tabelle auf.In the illustration, transaction T1 has a dependency on transaction T2 for the Part table lock resource. Entsprechend weist Transaktion T2 eine Abhängigkeit von Transaktion T1 für die Sperrressource der Supplier-Tabelle auf.Similarly, transaction T2 has a dependency on transaction T1 for the Supplier table lock resource. Da diese Abhängigkeiten einen Kreis bilden, besteht ein Deadlock zwischen den Transaktionen T1 und T2.Because these dependencies form a cycle, there is a deadlock between transactions T1 and T2.

Deadlocks können auch auftreten, wenn eine Tabelle partitioniert wird und für die LOCK_ESCALATION-Einstellung von ALTER TABLE die Option AUTO festgelegt ist.Deadlocks can also occur when a table is partitioned and the LOCK_ESCALATION setting of ALTER TABLE is set to AUTO. Ist für LOCK_ESCALATION die Option AUTO festgelegt, nimmt die Parallelität durch Unterstützung der Sperre von Tabellenpartitionen auf HoBT-Ebene anstatt auf TABLE-Ebene durch SQL Server-Datenbank-EngineSQL Server Database Engine zu.When LOCK_ESCALATION is set to AUTO, concurrency increases by allowing the SQL Server-Datenbank-EngineSQL Server Database Engine to lock table partitions at the HoBT level instead of at the table level. Wenn jedoch separate Transaktionen Partitionssperren in eine Tabelle aufnehmen und in der anderen Partitionstransaktion eine Sperre hinzugefügt werden soll, wird hiermit ein Deadlock verursacht.However, when separate transactions hold partition locks in a table and want a lock somewhere on the other transactions partition, this causes a deadlock. Diese Art Deadlock kann durch Festlegen von TABLE für LOCK_ESCALATION vermieden werden, auch wenn mit dieser Einstellung die Parallelität verringert wird, indem große Updates gezwungen werden, auf eine Tabellensperre zu warten.This type of deadlock can be avoided by setting LOCK_ESCALATION to TABLE; although this setting will reduce concurrency by forcing large updates to a partition to wait for a table lock.

Erkennen und Beenden von DeadlocksDetecting and Ending Deadlocks

Ein Deadlock tritt auf, wenn zwei Tasks einander dauerhaft gegenseitig blockieren, weil jeder der Tasks eine Sperre für eine Ressource aufrecht erhält, die die anderen Tasks zu sperren versuchen.A deadlock occurs when two or more tasks permanently block each other by each task having a lock on a resource which the other tasks are trying to lock. Die folgende Abbildung zeigt den Deadlockstatus auf hoher Ebene, wobei Folgendes gilt.The following graph presents a high level view of a deadlock state where:

  • Task T1 erhält eine Sperre für Ressource R1 aufrecht (wird durch den Pfeil von R1 zu T1 angezeigt) und hat eine Sperre für Ressource R2 angefordert (wird durch den Pfeil von T1 zu R2 angezeigt).Task T1 has a lock on resource R1 (indicated by the arrow from R1 to T1) and has requested a lock on resource R2 (indicated by the arrow from T1 to R2).
  • Task T2 erhält eine Sperre für Ressource R2 aufrecht (wird durch den Pfeil von R2 zu T1 angezeigt) und hat eine Sperre für Ressource R1 angefordert (wird durch den Pfeil von T2 zu R1 angezeigt).Task T2 has a lock on resource R2 (indicated by the arrow from R2 to T2) and has requested a lock on resource R1 (indicated by the arrow from T2 to R1).
  • Da keiner der Tasks fortgesetzt werden kann, bevor eine Ressource verfügbar ist, und keine der Ressourcen freigegeben werden kann, bevor ein Task fortgesetzt wird, ist ein Deadlock vorhanden.Because neither task can continue until a resource is available and neither resource can be released until a task continues, a deadlock state exists.

Diagramm mit Tasks im Deadlockstatus

SQL Server-Datenbank-EngineSQL Server Database Engine erkennt Deadlockzyklen in SQL ServerSQL Server automatisch.The SQL Server-Datenbank-EngineSQL Server Database Engine automatically detects deadlock cycles within SQL ServerSQL Server. SQL Server-Datenbank-EngineSQL Server Database Engine wählt eine der Sitzungen als Deadlockopfer aus, und die aktuelle Transaktion wird mit einem Fehler beendet, um den Deadlock zu durchbrechen.The SQL Server-Datenbank-EngineSQL Server Database Engine chooses one of the sessions as a deadlock victim and the current transaction is terminated with an error to break the deadlock.

Ressourcen, die an einem Deadlock beteiligt sein könnenResources that can Deadlock

Für jede Benutzersitzung werden möglicherweise ein oder mehrere Tasks ausgeführt, von denen jeder Task eine Vielzahl von Ressourcen abruft oder auf den Abruf wartet.Each user session might have one or more tasks running on its behalf where each task might acquire or wait to acquire a variety of resources. Die folgenden Typen von Ressourcen können eine Blockierung bewirken, die zu einem Deadlock führt.The following types of resources can cause blocking that could result in a deadlock.

  • Sperren:Locks. Das Warten auf den Abruf von Sperren für Ressourcen, z. B. Objekte, Seiten, Zeilen, Metadaten und Anwendungen, kann einen Deadlock verursachen.Waiting to acquire locks on resources, such as objects, pages, rows, metadata, and applications can cause deadlock. Transaktion T1 besitzt z. B. eine freigegebene (S) Sperre für Zeile r1 und wartet darauf, eine exklusive (X) Sperre für r2 zu erhalten.For example, transaction T1 has a shared (S) lock on row r1 and is waiting to get an exclusive (X) lock on r2. Transaktion T2 besitzt eine freigegebene (S) Sperre für Zeile r2 und wartet darauf, eine exklusive (X) Sperre für Zeile r1 zu erhalten.Transaction T2 has a shared (S) lock on r2 and is waiting to get an exclusive (X) lock on row r1. Dies führt zu einem Sperrenzyklus, in dem T1 und T2 darauf warten, dass die jeweils andere Transaktion die gesperrten Ressourcen freigibt.This results in a lock cycle in which T1 and T2 wait for each other to release the locked resources.

  • Arbeitsthreads:Worker threads. Ein Task in der Warteschlange, der auf einen verfügbaren Arbeitsthread wartet, kann einen Deadlock verursachen.A queued task waiting for an available worker thread can cause deadlock. Wenn der Task in der Warteschlange Ressourcen besitzt, die alle Arbeitsthreads blockieren, führt dies zu einem Deadlock.If the queued task owns resources that are blocking all worker threads, a deadlock will result. Sitzung S1 startet z. B. eine Transaktion, ruft eine freigegebene (S) Sperre für Zeile r1 ab und wird dann in den Ruhezustand versetzt.For example, session S1 starts a transaction and acquires a shared (S) lock on row r1 and then goes to sleep. Aktive Sitzungen, die für alle verfügbaren Arbeitsthreads ausgeführt werden, versuchen, exklusive (X) Sperren für Zeile r1 abzurufen.Active sessions running on all available worker threads are trying to acquire exclusive (X) locks on row r1. Da Sitzung S1 keinen Arbeitsthread abrufen kann, kann kein Commit für die Transaktion ausgeführt und die Sperre für Zeile r1 nicht freigegeben werden.Because session S1 cannot acquire a worker thread, it cannot commit the transaction and release the lock on row r1. Das Ergebnis ist ein Deadlock.This results in a deadlock.

  • SpeicherMemory. Wenn gleichzeitige Anforderungen auf Arbeitsspeicherzuweisungen warten, die mit dem verfügbaren Arbeitsspeicher nicht befriedigt werden können, kann ein Deadlock auftreten.When concurrent requests are waiting for memory grants that cannot be satisfied with the available memory, a deadlock can occur. Zwei gleichzeitige Abfragen, Q1 und Q2, werden z. B. als benutzerdefinierte Funktionen ausgeführt, die 10 MB bzw. 20 MB Arbeitsspeicher abrufen.For example, two concurrent queries, Q1 and Q2, execute as user-defined functions that acquire 10MB and 20MB of memory respectively. Wenn jede der Abfragen 30 MB benötigt und der gesamte verfügbare Arbeitsspeicher 20 MB beträgt, müssen Q1 und Q2 warten, bis die jeweils andere Transaktion Arbeitsspeicher freigibt; dies führt zu einem Deadlock.If each query needs 30MB and the total available memory is 20MB, then Q1 and Q2 must wait for each other to release memory, and this results in a deadlock.

  • Ressourcen in Verbindung mit einer parallelen Abfrageausführung:Parallel query execution-related resources. Coordinator-, Producer- oder Consumer-Threads, die mit einem Austauschport verknüpft sind, können einander blockieren und einen Deadlock verursachen, wenn mindestens ein weiterer Prozess eingeschlossen ist, der nicht Teil der parallelen Abfrage ist.Coordinator, producer, or consumer threads associated with an exchange port may block each other causing a deadlock usually when including at least one other process that is not a part of the parallel query. Wenn also eine parallele Abfrageausführung gestartet wird, bestimmt SQL ServerSQL Server den Grad des Parallelismus oder die Anzahl der Arbeitsthreads auf Basis der aktuellen Arbeitsauslastung.Also, when a parallel query starts execution, SQL ServerSQL Server determines the degree of parallelism, or the number of worker threads, based upon the current workload. Ein Deadlock kann auftreten, wenn sich die Arbeitsauslastung des Systems unerwartet ändert. Das ist beispielsweise der Fall, wenn neue Abfragen auf dem Server gestartet werden oder im System nicht mehr genügend Arbeitsthreads vorhanden sind.If the system workload unexpectedly changes, for example, where new queries start running on the server or the system runs out of worker threads, then a deadlock could occur.

  • MARS-Ressourcen (Multiple Active Result Sets):Multiple Active Result Sets (MARS) resources. Diese Ressourcen werden zum Steuern des Interleavings mehrerer aktiver Anforderungen unter MARS verwendet.These resources are used to control interleaving of multiple active requests under MARS. Weitere Informationen finden Sie unter Verwenden von Multiple Active Result Sets (MARS).For more information, see Using Multiple Active Result Sets (MARS).

    • Benutzerressource:User resource. Wenn ein Thread auf eine Ressource wartet, die potenziell von einer Benutzeranwendung gesteuert wird, wird die Ressource als externe oder Benutzerressource betrachtet und wie eine Sperre behandelt.When a thread is waiting for a resource that is potentially controlled by a user application, the resource is considered to be an external or user resource and is treated like a lock.

    • Sitzungsmutex:Session mutex. Die Tasks, die in einer Sitzung ausgeführt werden, sind verzahnt. Dies bedeutet, dass nur jeweils ein Task unter der Sitzung zu einem bestimmten Zeitpunkt ausgeführt werden kann.The tasks running in one session are interleaved, meaning that only one task can run under the session at a given time. Bevor der Task ausgeführt werden kann, muss er exklusiven Zugriff auf den Sitzungsmutex besitzen.Before the task can run, it must have exclusive access to the session mutex.

    • Transaktionsmutex:Transaction mutex. Alle Tasks, die in einer Transaktion ausgeführt werden, sind verzahnt. Dies bedeutet, dass nur jeweils ein Task unter der Transaktion zu einem bestimmten Zeitpunkt ausgeführt werden kann.All tasks running in one transaction are interleaved, meaning that only one task can run under the transaction at a given time. Bevor der Task ausgeführt werden kann, muss er exklusiven Zugriff auf den Transaktionsmutex besitzen.Before the task can run, it must have exclusive access to the transaction mutex.

    Damit ein Task unter MARS ausgeführt werden kann, muss er den Sitzungsmutex abrufen.In order for a task to run under MARS, it must acquire the session mutex. Wenn der Task unter einer Transaktion ausgeführt wird, muss er den Transaktionsmutex abrufen.If the task is running under a transaction, it must then acquire the transaction mutex. Auf diese Weise wird garantiert, dass nur jeweils ein Task gleichzeitig in einer bestimmten Sitzung und einer bestimmten Transaktion aktiviert ist.This guarantees that only one task is active at one time in a given session and a given transaction. Nachdem die erforderlichen Mutexe abgerufen wurden, kann der Task ausgeführt werden.Once the required mutexes have been acquired, the task can execute. Nachdem der Task beendet ist oder in der Mitte der Anforderung ein Ergebnis liefert, gibt er zuerst den Transaktionsmutex frei und dann den Sitzungsmutex (in umgekehrter Reihenfolge des Abrufs).When the task finishes, or yields in the middle of the request, it will first release transaction mutex followed by the session mutex in reverse order of acquisition. Mit diesen Ressourcen können jedoch Deadlocks auftreten.However, deadlocks can occur with these resources. Im folgenden Codebeispiel werden zwei Tasks, Benutzeranforderung U1 und Benutzeranforderung U2, in der gleichen Sitzung ausgeführt.In the following code example, two tasks, user request U1 and user request U2, are running in the same session.

    U1:    Rs1=Command1.Execute("insert sometable EXEC usp_someproc");  
    U2:    Rs2=Command2.Execute("select colA from sometable");  
    

    Die gespeicherte Prozedur, die durch Benutzeranforderung U1 ausgeführt wird, hat den Sitzungsmutex abgerufen.The stored procedure executing from user request U1 has acquired the session mutex. Wenn die gespeicherte Prozedur viel Zeit für die Ausführung benötigt, geht SQL Server-Datenbank-EngineSQL Server Database Engine davon aus, dass die gespeicherte Prozedur auf Eingaben vom Benutzer wartet.If the stored procedure takes a long time to execute, it is assumed by the SQL Server-Datenbank-EngineSQL Server Database Engine that the stored procedure is waiting for input from the user. Benutzeranforderung U2 wartet auf den Sitzungsmutex, während der Benutzer auf das Resultset aus U2 wartet, und U1 wartet auf eine Benutzerressource.User request U2 is waiting for the session mutex while the user is waiting for the result set from U2, and U1 is waiting for a user resource. Logisch stellt sich der Deadlockstatus wie folgt dar:This is deadlock state logically illustrated as:

LogicFlowExamplec

DeadlockerkennungDeadlock Detection

Alle in diesem Abschnitt aufgeführten Ressourcen nehmen am SQL Server-Datenbank-EngineSQL Server Database Engine-Deadlockerkennungsschema teil.All of the resources listed in the section above participate in the SQL Server-Datenbank-EngineSQL Server Database Engine deadlock detection scheme. Die Deadlockerkennung wird von einem Sperrenüberwachungsthread ausgeführt, der periodisch alle Tasks in einer Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine durchsucht.Deadlock detection is performed by a lock monitor thread that periodically initiates a search through all of the tasks in an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine. Die folgenden Schritte beschreiben den Suchvorgang:The following points describe the search process:

  • Das Standardintervall beträgt 5 Sekunden.The default interval is 5 seconds.
  • Wenn der Sperrenüberwachungsthread Deadlocks findet, sinkt das Deadlockerkennungsintervall abhängig von der Häufigkeit von Deadlocks von 5 Sekunden auf bis zu 100 Millisekunden.If the lock monitor thread finds deadlocks, the deadlock detection interval will drop from 5 seconds to as low as 100 milliseconds depending on the frequency of deadlocks.
  • Wenn der Sperrenüberwachungsthread keine weiteren Deadlocks mehr findet, verlängert SQL Server-Datenbank-EngineSQL Server Database Engine die Intervalle zwischen den Suchvorgängen auf 5 Sekunden.If the lock monitor thread stops finding deadlocks, the SQL Server-Datenbank-EngineSQL Server Database Engine increases the intervals between searches to 5 seconds.
  • Wenn ein Deadlock gerade erkannt wurde, wird davon ausgegangen, dass die nächsten Threads, die auf eine Sperre warten müssen, in den Deadlockzyklus eingehen.If a deadlock has just been detected, it is assumed that the next threads that must wait for a lock are entering the deadlock cycle. Die ersten Wartevorgänge auf Sperren nach der Erkennung eines Deadlocks lösen sofort eine Deadlocksuche aus; es wird nicht auf das nächste Deadlockerkennungsintervall gewartet.The first couple of lock waits after a deadlock has been detected will immediately trigger a deadlock search rather than wait for the next deadlock detection interval. Wenn das aktuelle Intervall z. B. 5 Sekunden beträgt und soeben ein Deadlock erkannt wurde, löst der nächste Wartevorgang auf eine Sperre die Deadlockerkennung sofort aus.For example, if the current interval is 5 seconds, and a deadlock was just detected, the next lock wait will kick off the deadlock detector immediately. Wenn dieser Wartevorgang auf eine Sperre Teil eines Deadlocks ist, wird er sofort und nicht erst während der nächsten Deadlocksuche erkannt.If this lock wait is part of a deadlock, it will be detected right away rather than during next deadlock search.

SQL Server-Datenbank-EngineSQL Server Database Engine führt normalerweise nur regelmäßige Deadlockerkennung aus.The SQL Server-Datenbank-EngineSQL Server Database Engine typically performs periodic deadlock detection only. Da die Anzahl der vorgefundenen Deadlocks im System in der Regel gering ist, kann mithilfe der regelmäßigen Erkennung von Deadlocks der Aufwand der Deadlockerkennung im System gesenkt werden.Because the number of deadlocks encountered in the system is usually small, periodic deadlock detection helps to reduce the overhead of deadlock detection in the system.

Wenn die Sperrenüberwachung die Suche nach Deadlocks für einen bestimmten Thread initiiert, wird die Ressource identifiziert, auf die der Thread wartet.When the lock monitor initiates deadlock search for a particular thread, it identifies the resource on which the thread is waiting. Die Sperrenüberwachung findet dann den (die) Besitzer dieser Ressource und führt rekursiv die Deadlocksuche für diese Threads fort, bis ein Zyklus gefunden wird.The lock monitor then finds the owner(s) for that particular resource and recursively continues the deadlock search for those threads until it finds a cycle. Ein auf diese Art identifizierter Zyklus bildet einen Deadlock.A cycle identified in this manner forms a deadlock.

Nachdem ein Deadlock erkannt wurde, beendet SQL Server-Datenbank-EngineSQL Server Database Engine den Deadlock, indem einer der Threads als Deadlockopfer ausgewählt wird.After a deadlock is detected, the SQL Server-Datenbank-EngineSQL Server Database Engine ends a deadlock by choosing one of the threads as a deadlock victim. SQL Server-Datenbank-EngineSQL Server Database Engine beendet den aktuellen Batch, der für den Thread ausgeführt wird, führt ein Rollback der Transaktion des Deadlockopfers aus und gibt den Fehler 1205 an die Anwendung zurück.The SQL Server-Datenbank-EngineSQL Server Database Engine terminates the current batch being executed for the thread, rolls back the transaction of the deadlock victim, and returns a 1205 error to the application. Durch den Rollback der Transaktion für das Deadlockopfer werden alle von der Transaktion aufrecht erhaltenen Sperren freigegeben.Rolling back the transaction for the deadlock victim releases all locks held by the transaction. Auf diese Weise kann die Sperre der Transaktionen der anderen Threads aufgehoben werden, und diese können fortgesetzt werden.This allows the transactions of the other threads to become unblocked and continue. Der Fehler 1205 (Deadlockopfer) zeichnet Informationen zu den an einem Deadlock beteiligten Threads und Ressourcen im Fehlerprotokoll auf.The 1205 deadlock victim error records information about the threads and resources involved in a deadlock in the error log.

Standardmäßig wählt SQL Server-Datenbank-EngineSQL Server Database Engine die Sitzung als Deadlockopfer aus, die die Transaktion ausführt, für die mit dem geringsten Aufwand ein Rollback ausgeführt werden kann.By default, the SQL Server-Datenbank-EngineSQL Server Database Engine chooses as the deadlock victim the session running the transaction that is least expensive to roll back. Alternativ kann ein Benutzer mithilfe der SET DEADLOCK_PRIORITY-Anweisung die Priorität der Sitzungen im Falle eines Deadlocks angeben.Alternatively, a user can specify the priority of sessions in a deadlock situation using the SET DEADLOCK_PRIORITY statement. DEADLOCK_PRIORITY kann auf LOW, NORMAL oder HIGH oder alternativ auf einen beliebigen ganzzahligen Wert im Bereich zwischen -10 und 10 festgelegt werden.DEADLOCK_PRIORITY can be set to LOW, NORMAL, or HIGH, or alternatively can be set to any integer value in the range (-10 to 10). Die Deadlockpriorität ist standardmäßig NORMAL.The deadlock priority defaults to NORMAL. Wenn die Sitzungen verschiedene Deadlockprioritäten besitzen, wird die Sitzung mit der niedrigeren Deadlockpriorität als Deadlockopfer ausgewählt.If two sessions have different deadlock priorities, the session with the lower priority is chosen as the deadlock victim. Wurde für beide Sitzungen die gleiche Deadlockprioriät festgelegt, wird diejenige Sitzung als Deadlockopfer ausgewählt, für die der Rollback weniger aufwändig ist.If both sessions have the same deadlock priority, the session with the transaction that is least expensive to roll back is chosen. Wenn die am Deadlockzyklus beteiligten Sitzungen die gleiche Deadlockpriorität und die gleichen Kosten besitzen, wird das Opfer zufällig ausgewählt.If sessions involved in the deadlock cycle have the same deadlock priority and the same cost, a victim is chosen randomly.

Wenn CLR verwendet wird, erkennt der Deadlockmonitor automatisch Deadlocks für Synchronisierungsressourcen (Überwachungsprogramme, Leser/Schreibersperre und Threadjoin), auf die in verwalteten Prozeduren zugegriffen wird.When working with CLR, the deadlock monitor automatically detects deadlock for synchronization resources (monitors, reader/writer lock and thread join) accessed inside managed procedures. Der Deadlock wird jedoch behoben, indem eine Ausnahme in der Prozedur ausgelöst wird, die als Deadlockopfer ausgewählt wurde.However, the deadlock is resolved by throwing an exception in the procedure that was selected to be the deadlock victim. Beachten Sie unbedingt, dass die Ausnahme nicht automatisch Ressourcen freigibt, die sich zurzeit im Besitz des Opfers befinden; die Ressourcen müssen explizit freigegeben werden.It is important to understand that the exception does not automatically release resources currently owned by the victim; the resources must be explicitly released. Die zum Identifizieren eines Deadlockopfers verwendete Ausnahme kann konsistent mit dem Verhalten der Ausnahme abgefangen und behandelt werden.Consistent with exception behavior, the exception used to identify a deadlock victim can be caught and dismissed.

Tools zum Anzeigen von DeadlockinformationenDeadlock Information Tools

Zum Anzeigen von Deadlockinformationen werden in SQL Server-Datenbank-EngineSQL Server Database Engine Überwachungstools in Form einer system_health xEvent-Sitzung, zwei Ablaufverfolgungsflags sowie das Deadlock Graph-Ereignis in SQL Profiler bereitgestellt.To view deadlock information, the SQL Server-Datenbank-EngineSQL Server Database Engine provides monitoring tools in the form of the system_health xEvent session, two trace flags, and the deadlock graph event in SQL Profiler.

Erweitertes Deadlock-EreignisDeadlock Extended Event

Ab SQL Server 2012 (11.x)SQL Server 2012 (11.x) sollte das erweiterte Ereignis xml_deadlock_report (xEvent) anstelle der Ereignisklasse des Deadlock-Graphen in der SQL-Ablaufverfolgung oder in SQL Server Profiler verwendet werden.Starting with SQL Server 2012 (11.x)SQL Server 2012 (11.x), the xml_deadlock_report Extended Event (xEvent) should be used instead of the Deadlock graph event class in SQL Trace or SQL Profiler.

Ebenfalls ab SQL Server 2012 (11.x)SQL Server 2012 (11.x) erfasst die system_health-Sitzung bei Auftreten eines Deadlock alle xml_deadlock_report-xEvents, die den Deadlockgraphen enthalten.Also starting with SQL Server 2012 (11.x)SQL Server 2012 (11.x), when deadlocks occur, the system_health session captures all xml_deadlock_report xEvents which contain the deadlock graph. Da die system_health-Sitzung standardmäßig aktiviert ist, ist es nicht erforderlich, eine eigene xEvent-Sitzung zu konfigurieren, um Deadlock-Informationen zu sammeln.Because the system_health session is enabled by default, it's not required that a separate xEvent session is configured to capture deadlock information.

Der in der Regel erfasste Deadlock Graph verfügt über drei unterschiedliche Knoten:The deadlock graph captured typically has three distinct nodes:

  • victim-list:victim-list. Prozessbezeichner des Deadlockopfers.The deadlock victim process identifier.
  • process-list:process-list. Informationen zu allen am Deadlock beteiligten Prozessen.Information on all the processes involved in the deadlock.
  • resource-list:resource-list. Informationen zu den am Deadlock beteiligten Ressourcen.Information about the resources involved in the deadlock.

Das folgende Beispiel zeigt, wie Management StudioManagement Studio beim Öffnen der system_health-Sitzungsdatei oder des -Ringpuffers (sofern der xml_deadlock_report-xEvent aufgezeichnet wird) eine grafische Darstellung der an einem Deadlock beteiligten Tasks und Ressourcen bereitstellt:Opening the system_health session file or ring buffer, if the xml_deadlock_report xEvent is recorded, Management StudioManagement Studio presents a graphical depiction of the tasks and resources involved in a deadlock, as seen in the following example:

xEvent-Deadlock-Graph

Die folgende Abfrage kann alle Deadlock-Ereignisse anzeigen, die vom Ringpuffer der system_health-Sitzung erfasst wurden:The following query can view all deadlock events captured by the system_health session ring buffer:

SELECT xdr.value('@timestamp', 'datetime') AS [Date],
    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 [Date] DESC

Hier ist das Resultset.Here is the result set.

system_health_qry

Das folgende Beispiel zeigt die Ausgabe nach dem Klicken auf den ersten Link der vorhergehenden Ergebnisse:The following example shows the output, after clicking on the first link of the result above:

<event name="xml_deadlock_report" package="sqlserver" timestamp="2018-02-18T08:26:24.698Z">
  <data name="xml_report">
    <type name="xml" package="package0" />
    <value>
      <deadlock>
        <victim-list>
          <victimProcess id="process27b9b0b9848" />
        </victim-list>
        <process-list>
          <process id="process27b9b0b9848" taskpriority="0" logused="0" waitresource="KEY: 5:72057594214350848 (1a39e6095155)" waittime="1631" ownerId="11088595" transactionname="SELECT" lasttranstarted="2018-02-18T00:26:23.073" XDES="0x27b9f79fac0" lockMode="S" schedulerid="9" kpid="15336" status="suspended" spid="62" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2018-02-18T00:26:22.893" lastbatchcompleted="2018-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="7908" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088595" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
            <executionStack>
              <frame procname="AdventureWorks2016CTP3.dbo.p1" line="3" stmtstart="78" stmtend="180" sqlhandle="0x0300050020766505ca3e07008ba8000001000000000000000000000000000000000000000000000000000000">
SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+    </frame>
              <frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x020000006263ec01ebb919c335024a072a2699958d3fcce60000000000000000000000000000000000000000">
unknown    </frame>
            </executionStack>
            <inputbuf>
SET NOCOUNT ON
WHILE (1=1) 
BEGIN
    EXEC p1 4
END
   </inputbuf>
          </process>
          <process id="process27b9ee33c28" taskpriority="0" logused="252" waitresource="KEY: 5:72057594214416384 (e5b3d7e750dd)" waittime="1631" ownerId="11088593" transactionname="UPDATE" lasttranstarted="2018-02-18T00:26:23.073" XDES="0x27ba15a4490" lockMode="X" schedulerid="6" kpid="5584" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2018-02-18T00:26:22.890" lastbatchcompleted="2018-02-18T00:26:22.890" lastattention="1900-01-01T00:00:00.890" clientapp="SQLCMD" hostname="ContosoServer" hostpid="15316" loginname="CONTOSO\user" isolationlevel="read committed (2)" xactid="11088593" currentdb="5" lockTimeout="4294967295" clientoption1="538968096" clientoption2="128056">
            <executionStack>
              <frame procname="AdventureWorks2016CTP3.dbo.p2" line="3" stmtstart="76" stmtend="150" sqlhandle="0x03000500599a5906ce3e07008ba8000001000000000000000000000000000000000000000000000000000000">
UPDATE t1 SET c2 = c2+1 WHERE c1 = @p    </frame>
              <frame procname="adhoc" line="4" stmtstart="82" stmtend="98" sqlhandle="0x02000000008fe521e5fb1099410048c5743ff7da04b2047b0000000000000000000000000000000000000000">
unknown    </frame>
            </executionStack>
            <inputbuf>
SET NOCOUNT ON
WHILE (1=1) 
BEGIN
    EXEC p2 4
END
   </inputbuf>
          </process>
        </process-list>
        <resource-list>
          <keylock hobtid="72057594214350848" dbid="5" objectname="AdventureWorks2016CTP3.dbo.t1" indexname="cidx" id="lock27b9dd26a00" mode="X" associatedObjectId="72057594214350848">
            <owner-list>
              <owner id="process27b9ee33c28" mode="X" />
            </owner-list>
            <waiter-list>
              <waiter id="process27b9b0b9848" mode="S" requestType="wait" />
            </waiter-list>
          </keylock>
          <keylock hobtid="72057594214416384" dbid="5" objectname="AdventureWorks2016CTP3.dbo.t1" indexname="idx1" id="lock27afa392600" mode="S" associatedObjectId="72057594214416384">
            <owner-list>
              <owner id="process27b9b0b9848" mode="S" />
            </owner-list>
            <waiter-list>
              <waiter id="process27b9ee33c28" mode="X" requestType="wait" />
            </waiter-list>
          </keylock>
        </resource-list>
      </deadlock>
    </value>
  </data>
</event>

Weitere Informationen finden Sie unter Verwenden der system_health-Sitzung.For more information, see Use the system_health Session

Ablaufverfolgungsflag 1204 und Ablaufverfolgungsflag 1222Trace Flag 1204 and Trace Flag 1222

Wenn Deadlocks auftreten, geben die Ablaufverfolgungsflags 1204 und 1222 Informationen zurück, die im SQL ServerSQL Server-Fehlerprotokoll erfasst werden.When deadlocks occur, trace flag 1204 and trace flag 1222 return information that is captured in the SQL ServerSQL Server error log. Ablaufverfolgungsflag 1204 meldet von jedem im Deadlock beteiligten Knoten formatierte Deadlockinformationen.Trace flag 1204 reports deadlock information formatted by each node involved in the deadlock. Ablaufverfolgungsflag 1222 formatiert Deadlockinformationen, zunächst prozessweise, anschließend Ressource für Ressource.Trace flag 1222 formats deadlock information, first by processes and then by resources. Es ist möglich, beide Ablaufverfolgungsflags zu aktivieren, um zwei Darstellungen desselben Deadlockereignisses zu erhalten.It is possible to enable both trace flags to obtain two representations of the same deadlock event.

Wichtig

Vermeiden Sie die Verwendung der Ablaufverfolgungsflags 1204 und 1222 für Systeme mit hoher Arbeitsauslastung, die Deadlocks verursachen.Avoid using trace flag 1204 and 1222 on workload-intensive systems that are causing deadlocks. Die Verwendung dieser Ablaufverfolgungsflags kann zu Leistungsproblemen führen.Using these trace flags may introduce performance issues. Verwenden Sie stattdessen das erweiterte Deadlock-Ereignis (#deadlock_xevent).Instead, use the Deadlock Extended Event(#deadlock_xevent).

Zur weiteren Definition der Eigenschaften der Ablaufverfolgungsflags 1204 und 1222 werden in der folgenden Tabelle die Ähnlichkeiten und Unterschiede aufgeführt.In addition to defining the properties of trace flag 1204 and 1222, the following table also shows the similarities and differences.

EigenschaftProperty Ablaufverfolgungsflag 1204 und Ablaufverfolgungsflag 1222Trace Flag 1204 and Trace Flag 1222 Nur Ablaufverfolgungsflag 1204Trace Flag 1204 only Nur Ablaufverfolgungsflag 1222Trace Flag 1222 only
AusgabeformatOutput format Die Ausgabe wird im SQL ServerSQL Server-Fehlerprotokoll erfasst.Output is captured in the SQL ServerSQL Server error log. Ist auf die im Deadlock beteiligten Knoten ausgerichtet.Focused on the nodes involved in the deadlock. Jeder Knoten verfügt über einen dedizierten Abschnitt, wobei der letzte Abschnitt das Deadlockopfer beschreibt.Each node has a dedicated section, and the final section describes the deadlock victim. Gibt Informationen im XML-ähnlichen Format zurück, das einer XSD-Sprache (XML Schema Definition) nicht entspricht.Returns information in an XML-like format that does not conform to an XML Schema Definition (XSD) schema. Das Format verfügt über drei große Abschnitte.The format has three major sections. Der erste Abschnitt deklariert das Deadlockopfer.The first section declares the deadlock victim. Der zweite Abschnitt beschreibt die jeweiligen im Deadlock beteiligten Prozesse.The second section describes each process involved in the deadlock. Der dritte Abschnitt beschreibt die Ressourcen, die den Knoten des Ablaufverfolgungsflags 1204 entsprechen.The third section describes the resources that are synonymous with nodes in trace flag 1204.
Identifizieren von AttributenIdentifying attributes SPID:<x> ECID:<x>. :SPID:<x> ECID:<x>. Identifiziert den Thread der Systemprozess-ID bei parallelen Prozessen.Identifies the system process ID thread in cases of parallel processes. Der Eintrag SPID:<x> ECID:0, in dem <x> durch den SPID-Wert ersetzt wird, stellt den Hauptthread dar.The entry SPID:<x> ECID:0, where <x> is replaced by the SPID value, represents the main thread. Der Eintrag SPID:<x> ECID:<y>, in dem <x> durch den SPID-Wert ersetzt wird und <y> größer als 0 ist, stellt die Unterthreads desselben SPID-Werts dar.The entry SPID:<x> ECID:<y>, where <x> is replaced by the SPID value and <y> is greater than 0, represents the sub-threads for the same SPID.

BatchID (sbid für Ablaufverfolgungsflag 1222):BatchID (sbid for trace flag 1222). Identifiziert den Batch, von dem die Codeausführung angefragt oder eine Sperre aufrechterhalten wird.Identifies the batch from which code execution is requesting or holding a lock. Wenn MARS (Multiple Active Result Sets) deaktiviert sind, ist der BatchID-Wert gleich 0.When Multiple Active Result Sets (MARS) is disabled, the BatchID value is 0. Wenn MARS aktiviert sind, kann der Wert für aktive Batches von 1 bis n reichen.When MARS is enabled, the value for active batches is 1 to n. Sind in der Sitzung keine aktiven Batches vorhanden, ist der BatchID-Wert gleich 0.If there are no active batches in the session, BatchID is 0.

Mode:Mode. Gibt den Typ der Sperre für eine bestimmte Ressource an, die angefragt, erteilt oder von einem Thread erwartet wird.Specifies the type of lock for a particular resource that is requested, granted, or waited on by a thread. Dies kann eine beabsichtigte freigegebene Sperre (Intent Shared, IS), eine freigegebene Sperre (Shared), eine Updatesperre (Update, U), eine beabsichtigte exklusive Sperre (Intent Exclusive, IX), eine freigegebene mit beabsichtigten exklusiven Sperren (Shared with Intent Exclusive, SIX) und eine exklusive Sperre (Exclusive, X) sein.Mode can be IS (Intent Shared), S (Shared), U (Update), IX (Intent Exclusive), SIX (Shared with Intent Exclusive), and X (Exclusive).

Line # (line für Ablaufverfolgungsflag 1222):Line # (line for trace flag 1222). Listet die Zeilennummer des aktuellen Batches von Anweisungen auf, die beim Auftreten des Deadlocks ausgeführt wurden.Lists the line number in the current batch of statements that was being executed when the deadlock occurred.

Input Buf (inputbuf für Ablaufverfolgungsflag 1222):Input Buf (inputbuf for trace flag 1222). Listet alle Anweisungen im aktuellen Batch auf.Lists all the statements in the current batch.
Node:Node. Stellt die Eintragsnummer in der Deadlockkette dar.Represents the entry number in the deadlock chain.

Lists:Lists. Der Sperrenbesitzer kann Bestandteil dieser Listen sein:The lock owner can be part of these lists:

Grant List:Grant List. Zählt die aktuellen Besitzer der Ressource auf.Enumerates the current owners of the resource.

Convert List:Convert List. Zählt die aktuellen Besitzer auf, die versuchen, ihre Sperren in eine höhere Ebene zu konvertieren.Enumerates the current owners that are trying to convert their locks to a higher level.

Wait List:Wait List. Zählt die neuesten Sperrenanforderungen für die Ressource auf.Enumerates current new lock requests for the resource.

Statement Type:Statement Type. Beschreibt den Typ der DML-Anweisung (SELECT, INSERT, UPDATE oder DELETE), für die Threads über Berechtigungen verfügen.Describes the type of DML statement (SELECT, INSERT, UPDATE, or DELETE) on which the threads have permissions.

Victim Resource Owner:Victim Resource Owner. Gibt den teilnehmenden Thread an, den SQL ServerSQL Server zum Durchbrechen des Deadlockzyklus als Opfer auswählt.Specifies the participating thread that SQL ServerSQL Server chooses as the victim to break the deadlock cycle. Der ausgewählte Thread und alle vorhandenen Unterthreads werden beendet.The chosen thread and all existing sub-threads are terminated.

Next Branch:Next Branch. Stellt die beiden oder mehreren im Deadlockzyklus beteiligten Unterthreads desselben SPID-Werts dar.Represents the two or more sub-threads from the same SPID that are involved in the deadlock cycle.
deadlock victim:deadlock victim. Stellt die physische Speicheradresse des Tasks dar (siehe sys.dm_os_tasks (Transact-SQL)), der als Deadlockopfer ausgewählt wurde.Represents the physical memory address of the task (see sys.dm_os_tasks (Transact-SQL)) that was selected as a deadlock victim. Im Fall eines nicht aufgelösten Deadlocks kann diese Angabe 0 (Null) sein.It may be 0 (zero) in the case of an unresolved deadlock. Ein Task, für den ein Rollback ausgeführt wird, kann nicht als Deadlockopfer ausgewählt werden.A task that is rolling back cannot be chosen as a deadlock victim.

executionstack:executionstack. Stellt den Transact-SQLTransact-SQL-Code dar, der zum Zeitpunkt des Auftretens des Deadlocks ausgeführt wird.Represents Transact-SQLTransact-SQL code that is being executed at the time the deadlock occurs.

priority:priority. Stellt die Deadlockpriorität dar.Represents deadlock priority. Unter bestimmten Umständen kann SQL Server-Datenbank-EngineSQL Server Database Engine die Deadlockpriorität für eine kurze Zeitspanne ändern, um eine bessere Parallelität zu erzielen.In certain cases, the SQL Server-Datenbank-EngineSQL Server Database Engine may opt to alter the deadlock priority for a short duration to achieve better concurrency.

logused:logused. Vom Task verwendeter Protokollspeicherplatz.Log space used by the task.

owner id: Die ID der Transaktion, die die Steuerung der Anforderung durchführt.owner id. The ID of the transaction that has control of the request.

status:status. Der Status des Tasks.State of the task. Ist einer der folgenden Werte:It is one of the following values:

>> pending:>> pending. Warten auf einen Arbeitsthread.Waiting for a worker thread.

>> runnable:>> runnable. Bereit zum Ausführen, jedoch wird auf das Eintreffen eines Quantums gewartet.Ready to run but waiting for a quantum.

>> running:>> running. Wird derzeit auf dem Zeitplanungsmodul ausgeführt.Currently running on the scheduler.

>> suspended:>> suspended. Die Ausführung wird angehalten.Execution is suspended.

>> done:>> done. Der Task ist abgeschlossen.Task has completed.

>> spinloop:>> spinloop. Es wird auf die Verfügbarkeit eines Spinlocks gewartet.Waiting for a spinlock to become free.

waitresource:waitresource. Die vom Task benötigte Ressource.The resource needed by the task.

waittime:waittime. Zeitspanne in Millisekunden, die auf die Ressource gewartet wurde.Time in milliseconds waiting for the resource.

schedulerid:schedulerid. Diesem Task zugeordnetes Zeitplanungsmodul.Scheduler associated with this task. Siehe sys.dm_os_schedulers (Transact-SQL).See sys.dm_os_schedulers (Transact-SQL).

hostname:hostname. Der Name der Arbeitsstation.The name of the workstation.

isolationlevel:isolationlevel. Die aktuelle Isolationsstufe für Transaktionen.The current transaction isolation level.

Xactid:Xactid. Die ID der Transaktion, die die Steuerung der Anforderung durchführt.The ID of the transaction that has control of the request.

currentdb:currentdb. Die ID der Datenbank.The ID of the database.

lastbatchstarted:lastbatchstarted. Uhrzeit des letzten Starts der Batchausführung durch einen Clientprozess.The last time a client process started batch execution.

lastbatchcompleted:lastbatchcompleted. Uhrzeit des letzten Abschlusses der Batchausführung durch einen Clientprozess.The last time a client process completed batch execution.

clientoption1 und clientoption2:clientoption1 and clientoption2. SET-Optionen für diese Clientverbindung.Set options on this client connection. Es handelt sich um ein Bitmuster, das Informationen zu Optionen enthält, die normalerweise durch SET-Anweisungen, z. B. SET NOCOUNT und SET XACTABORT, gesteuert werden.This is a bitmask that includes information about options usually controlled by SET statements such as SET NOCOUNT and SET XACTABORT.

associatedObjectId:associatedObjectId. Stellt die HoBT-ID (Heap- oder B-Struktur) dar.Represents the HoBT (heap or b-tree) ID.
RessourcenattributeResource attributes RID:RID. Identifiziert die einzelne Zeile innerhalb einer Tabelle, in der eine Sperre aufrechterhalten oder angefragt wird.Identifies the single row within a table on which a lock is held or requested. RID wird als RID dargestellt: db_id:file_id:page_no:row_no.RID is represented as RID: db_id:file_id:page_no:row_no. Beispiel: RID: 6:1:20789:0.For example, RID: 6:1:20789:0.

OBJECT:OBJECT. Identifiziert die Tabelle, in der eine Sperre aufrechterhalten oder angefragt wird.Identifies the table on which a lock is held or requested. OBJECT wird als OBJECT dargestellt: db_id:object_id.OBJECT is represented as OBJECT: db_id:object_id. Beispiel: TAB: 6:2009058193.For example, TAB: 6:2009058193.

KEY:KEY. Identifiziert den Schlüsselbereich innerhalb eines Indexes, in dem eine Sperre aufrechterhalten oder angefragt wird.Identifies the key range within an index on which a lock is held or requested. KEY wird als KEY dargestellt: db_id:hobt_id (Indexschlüssel-Hashwert).KEY is represented as KEY: db_id:hobt_id (index key hash value). Beispiel: KEY: 6:72057594057457664 (350007a4d329).For example, KEY: 6:72057594057457664 (350007a4d329).

PAG:PAG. Identifiziert die Seitenressource, in der eine Sperre aufrechterhalten oder angefragt wird.Identifies the page resource on which a lock is held or requested. PAG wird als PAG dargestellt: db_id:file_id:page_no.PAG is represented as PAG: db_id:file_id:page_no. Beispiel: PAG: 6:1:20789.For example, PAG: 6:1:20789.

EXT:EXT. Identifiziert die Blockstruktur.Identifies the extent structure. EXT wird als EXT dargestellt: db_id:file_id:extent_no.EXT is represented as EXT: db_id:file_id:extent_no. Beispiel: EXT: 6:1:9.For example, EXT: 6:1:9.

DB:DB. Identifiziert die Datenbanksperre.Identifies the database lock. DB wird auf eine der folgenden Arten dargestellt:DB is represented in one of the following ways:

DB: db_idDB: db_id

DB: db_id[BULK-OP-DB]: Identifiziert die von der Sicherungsdatenbank erstellte Datenbanksperre.DB: db_id[BULK-OP-DB], which identifies the database lock taken by the backup database.

DB: db_id[BULK-OP-LOG]: Identifiziert die vom Sicherungsprotokoll für diese bestimmte Datenbank erstellte Sperre.DB: db_id[BULK-OP-LOG], which identifies the lock taken by the backup log for that particular database.

APP:APP. Identifiziert die von einer Anwendungsressource erstellte Sperre.Identifies the lock taken by an application resource. APP wird als APP dargestellt: lock_resource.APP is represented as APP: lock_resource. Beispiel: APP: Formf370f478.For example, APP: Formf370f478.

METADATA:METADATA. Stellt die in einem Deadlock beteiligten Metadatenressourcen dar.Represents metadata resources involved in a deadlock. Da METADATA über viele Unterressourcen verfügt, hängt der zurückgegebene Wert von der Unterressource ab, für die ein Deadlock vorliegt.Because METADATA has many subresources, the value returned depends upon the subresource that has deadlocked. METADATA.USER_TYPE gibt beispielsweise user_type_id = <integer_value> zurück.For example, METADATA.USER_TYPE returns user_type_id = <integer_value>. Weitere Informationen zu METADATA-Ressourcen und -Unterressourcen finden Sie unter sys.dm_tran_locks (Transact-SQL).For more information about METADATA resources and subresources, see sys.dm_tran_locks (Transact-SQL).

HOBT:HOBT. Stellt eine in einem Deadlock beteiligte Heap- oder B-Struktur dar.Represents a heap or b-tree involved in a deadlock.
Gilt nicht ausschließlich für dieses Ablaufverfolgungsflag.None exclusive to this trace flag. Gilt nicht ausschließlich für dieses Ablaufverfolgungsflag.None exclusive to this trace flag.
Beispiel für Ablaufverfolgungsflag 1204Trace Flag 1204 Example

Im folgenden Beispiel wird die Ausgabe beim Aktivieren des Ablaufverfolgungsflags 1204 gezeigt.The following example shows the output when trace flag 1204 is turned on. Hierbei wird die Tabelle auf Knoten 1 als Heap ohne Indizes und die Tabelle auf Knoten 2 als Heap mit einem nicht gruppierten Index verwendet.In this case, the table in Node 1 is a heap with no indexes, and the table in Node 2 is a heap with a nonclustered index. Der Indexschlüssel auf Knoten 2 wird beim Auftreten des Deadlocks aktualisiert.The index key in Node 2 is being updated when the deadlock occurs.

Deadlock encountered .... Printing deadlock information  
Wait-for graph  
  
Node:1  
  
RID: 6:1:20789:0               CleanCnt:3 Mode:X Flags: 0x2  
 Grant List 0:  
   Owner:0x0315D6A0 Mode: X          
     Flg:0x0 Ref:0 Life:02000000 SPID:55 ECID:0 XactLockInfo: 0x04D9E27C  
   SPID: 55 ECID: 0 Statement Type: UPDATE Line #: 6  
   Input Buf: Language Event:   
BEGIN TRANSACTION  
   EXEC usp_p2  
 Requested By:   
   ResType:LockOwner Stype:'OR'Xdes:0x03A3DAD0   
     Mode: U SPID:54 BatchID:0 ECID:0 TaskProxy:(0x04976374) Value:0x315d200 Cost:(0/868)  
  
Node:2  
  
KEY: 6:72057594057457664 (350007a4d329) CleanCnt:2 Mode:X Flags: 0x0  
 Grant List 0:  
   Owner:0x0315D140 Mode: X          
     Flg:0x0 Ref:0 Life:02000000 SPID:54 ECID:0 XactLockInfo: 0x03A3DAF4  
   SPID: 54 ECID: 0 Statement Type: UPDATE Line #: 6  
   Input Buf: Language Event:   
     BEGIN TRANSACTION  
       EXEC usp_p1  
 Requested By:   
   ResType:LockOwner Stype:'OR'Xdes:0x04D9E258   
     Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)  
  
Victim Resource Owner:  
 ResType:LockOwner Stype:'OR'Xdes:0x04D9E258   
     Mode: U SPID:55 BatchID:0 ECID:0 TaskProxy:(0x0475E374) Value:0x315d4a0 Cost:(0/380)  
Beispiel für Ablaufverfolgungsflag 1222Trace Flag 1222 Example

Im folgenden Beispiel wird die Ausgabe beim Aktivieren des Ablaufverfolgungsflags 1222 gezeigt.The following example shows the output when trace flag 1222 is turned on. Hierbei wird eine Tabelle als Heap ohne Indizes und die andere Tabelle als Heap mit einem nicht gruppierten Index verwendet.In this case, one table is a heap with no indexes, and the other table is a heap with a nonclustered index. In der zweiten Tabelle wird der Indexschlüssel beim Auftreten des Deadlocks aktualisiert.In the second table, the index key is being updated when the deadlock occurs.

deadlock-list  
 deadlock victim=process689978  
  process-list  
   process id=process6891f8 taskpriority=0 logused=868   
   waitresource=RID: 6:1:20789:0 waittime=1359 ownerId=310444   
   transactionname=user_transaction   
   lasttranstarted=2005-09-05T11:22:42.733 XDES=0x3a3dad0   
   lockMode=U schedulerid=1 kpid=1952 status=suspended spid=54   
   sbid=0 ecid=0 priority=0 transcount=2   
   lastbatchstarted=2005-09-05T11:22:42.733   
   lastbatchcompleted=2005-09-05T11:22:42.733   
   clientapp=Microsoft SQL Server Management Studio - Query   
   hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user   
   isolationlevel=read committed (2) xactid=310444 currentdb=6   
   lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200  
    executionStack  
     frame procname=AdventureWorks2016.dbo.usp_p1 line=6 stmtstart=202   
     sqlhandle=0x0300060013e6446b027cbb00c69600000100000000000000  
     UPDATE T2 SET COL1 = 3 WHERE COL1 = 1;       
     frame procname=adhoc line=3 stmtstart=44   
     sqlhandle=0x01000600856aa70f503b8104000000000000000000000000  
     EXEC usp_p1       
    inputbuf  
      BEGIN TRANSACTION  
       EXEC usp_p1  
   process id=process689978 taskpriority=0 logused=380   
   waitresource=KEY: 6:72057594057457664 (350007a4d329)     
   waittime=5015 ownerId=310462 transactionname=user_transaction   
   lasttranstarted=2005-09-05T11:22:44.077 XDES=0x4d9e258 lockMode=U   
   schedulerid=1 kpid=3024 status=suspended spid=55 sbid=0 ecid=0   
   priority=0 transcount=2 lastbatchstarted=2005-09-05T11:22:44.077   
   lastbatchcompleted=2005-09-05T11:22:44.077   
   clientapp=Microsoft SQL Server Management Studio - Query   
   hostname=TEST_SERVER hostpid=2216 loginname=DOMAIN\user   
   isolationlevel=read committed (2) xactid=310462 currentdb=6   
   lockTimeout=4294967295 clientoption1=671090784 clientoption2=390200  
    executionStack  
     frame procname=AdventureWorks2016.dbo.usp_p2 line=6 stmtstart=200   
     sqlhandle=0x030006004c0a396c027cbb00c69600000100000000000000  
     UPDATE T1 SET COL1 = 4 WHERE COL1 = 1;       
     frame procname=adhoc line=3 stmtstart=44   
     sqlhandle=0x01000600d688e709b85f8904000000000000000000000000  
     EXEC usp_p2       
    inputbuf  
      BEGIN TRANSACTION  
        EXEC usp_p2      
  resource-list  
   ridlock fileid=1 pageid=20789 dbid=6 objectname=AdventureWorks2016.dbo.T2   
   id=lock3136940 mode=X associatedObjectId=72057594057392128  
    owner-list  
     owner id=process689978 mode=X  
    waiter-list  
     waiter id=process6891f8 mode=U requestType=wait  
   keylock hobtid=72057594057457664 dbid=6 objectname=AdventureWorks2016.dbo.T1   
   indexname=nci_T1_COL1 id=lock3136fc0 mode=X   
   associatedObjectId=72057594057457664  
    owner-list  
     owner id=process6891f8 mode=X  
    waiter-list  
     waiter id=process689978 mode=U requestType=wait  

Profiler Deadlock Graph-EreignisProfiler Deadlock Graph Event

Dies ist ein Ereignis in SQL Profiler, das eine grafische Darstellung der an einem Deadlock beteiligten Tasks und Ressourcen bereitstellt.This is an event in SQL Profiler that presents a graphical depiction of the tasks and resources involved in a deadlock. Im folgenden Beispiel wird die Ausgabe von SQL Profiler gezeigt, wenn das Deadlock Graph-Ereignis aktiviert ist.The following example shows the output from SQL Profiler when the deadlock graph event is turned on.

ProfilerDeadlockGraphc

Weitere Informationen zum Deadlockereignis finden Sie unter Lock:Deadlock (Ereignisklasse).For more information about the deadlock event, see Lock:Deadlock Event Class.

Weitere Informationen zum Ausführen von SQL Profiler Deadlock Graph finden Sie unter Speichern von Deadlock Graphs (SQL Server Profiler).For more information about running the SQL Profiler deadlock graph, see Save Deadlock Graphs (SQL Server Profiler).

Behandeln von DeadlocksHandling Deadlocks

Wenn eine SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz eine Transaktion als Deadlockopfer auswählt, beendet sie den aktuellen Batch, führt einen Rollback der Transaktion durch und gibt die Fehlermeldung 1205 an die Anwendung zurück.When an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine chooses a transaction as a deadlock victim, it terminates the current batch, rolls back the transaction, and returns error message 1205 to the application.

Your transaction (process ID #52) was deadlocked on {lock | communication buffer | thread} resources with another process and has been chosen as the deadlock victim. Rerun your transaction.

Da jede Anwendung, die Transact-SQLTransact-SQL-Abfragen sendet, als Deadlockopfer ausgewählt werden kann, sollten die Anwendungen über einen Fehlerhandler verfügen, der Fehlermeldung 1205 auffangen kann.Because any application submitting Transact-SQLTransact-SQL queries can be chosen as the deadlock victim, applications should have an error handler that can trap error message 1205. Wenn eine Anwendung den Fehler nicht auffängt, wird sie möglicherweise weiter ausgeführt, da nicht erkannt wird, dass ein Rollback für die zugehörige Transaktion ausgeführt wurde, und es können Fehler auftreten.If an application does not trap the error, the application can proceed unaware that its transaction has been rolled back and errors can occur.

Durch Implementieren eines Fehlerhandlers, der die Fehlermeldung 1205 abfängt, kann eine Anwendung den Deadlock verarbeiten und Abhilfemaßnahmen ergreifen, wie etwa die Abfrage, die am Deadlock beteiligt war, automatisch erneut abzusenden.Implementing an error handler that traps error message 1205 allows an application to handle the deadlock situation and take remedial action (for example, automatically resubmitting the query that was involved in the deadlock). Durch die automatische erneute Absendung der Abfrage ist es nicht notwendig, dass der Benutzer von dem Deadlock erfährt.By resubmitting the query automatically, the user does not need to know that a deadlock occurred.

Die Anwendung sollte kurzzeitig angehalten werden, bevor die Abfrage erneut abgesendet wird.The application should pause briefly before resubmitting its query. Auf diese Weise kann die andere Transaktion, die an einem Deadlock beteiligt ist, abgeschlossen werden und die Sperren freigeben, die einen Anteil am Deadlockzyklus hatten.This gives the other transaction involved in the deadlock a chance to complete and release its locks that formed part of the deadlock cycle. Die Wahrscheinlichkeit, dass ein Deadlock erneut auftritt, wenn die erneut abgesendete Abfrage ihre Sperren anfordert, wird so verringert.This minimizes the likelihood of the deadlock reoccurring when the resubmitted query requests its locks.

Minimieren von DeadlocksMinimizing Deadlocks

Obwohl Deadlocks nicht vollständig vermieden werden können, kann das Risiko eines Deadlocks durch das Befolgen bestimmter Codierungskonventionen minimiert werden.Although deadlocks cannot be completely avoided, following certain coding conventions can minimize the chance of generating a deadlock. Wenn die Anzahl der Deadlocks minimiert wird, können der Transaktionsdurchsatz erhöht und der Aufwand des Systems reduziert werden, und zwar aus folgenden Gründen:Minimizing deadlocks can increase transaction throughput and reduce system overhead because fewer transactions are:

  • Die Anzahl der Transaktionen, für die ein Rollback ausgeführt wird, durch den die von einer Transaktion ausgeführte Arbeit rückgängig gemacht wird, ist geringer.Rolled back, undoing all the work performed by the transaction.
  • Die Anzahl der Transaktionen, die von den Anwendungen erneut abgesendet werden, da für sie aufgrund des Deadlocks ein Rollback ausgeführt wurde, ist geringer.Resubmitted by applications because they were rolled back when deadlocked.

So kann das Risiko von Deadlocks minimiert werden:To help minimize deadlocks:

  • Greifen Sie in derselben Reihenfolge auf Objekte zu.Access objects in the same order.
  • Vermeiden Sie Benutzerinteraktionen in Transaktionen.Avoid user interaction in transactions.
  • Verwenden Sie kurze Transaktionen in einem einzigen Batch.Keep transactions short and in one batch.
  • Verwenden Sie eine niedrigere Isolationsstufe.Use a lower isolation level.
  • Verwenden Sie eine auf der Zeilenversionsverwaltung basierende Isolationsstufe.Use a row versioning-based isolation level.
    • Legen Sie die Datenbankoption READ_COMMITTED_SNAPSHOT auf ON fest, um die Verwendung der Zeilenversionsverwaltung für READ COMMITTED-Transaktionen zu aktivieren.Set READ_COMMITTED_SNAPSHOT database option ON to enable read-committed transactions to use row versioning.
    • Verwenden Sie die Momentaufnahmeisolation.Use snapshot isolation.
  • Verwenden Sie gebundene Verbindungen.Use bound connections.

Zugreifen auf Objekte in derselben ReihenfolgeAccess Objects in the same order

Wenn alle gleichzeitigen Transaktionen in derselben Reihenfolge auf Objekte zugreifen, treten Deadlocks seltener auf.If all concurrent transactions access objects in the same order, deadlocks are less likely to occur. Wenn beispielsweise zwei gleichzeitige Transaktionen jeweils zuerst die Supplier-Tabelle und anschließend die Part-Tabelle mit einer Sperre belegen, wird eine Transaktion für die Supplier-Tabelle blockiert, bis die andere abgeschlossen ist.For example, if two concurrent transactions obtain a lock on the Supplier table and then on the Part table, one transaction is blocked on the Supplier table until the other transaction is completed. Nachdem für die erste Transaktion ein Commit- oder Rollback-Vorgang ausgeführt wurde, wird die Ausführung der zweiten Transaktion fortgesetzt, und es tritt kein Deadlock auf.After the first transaction commits or rolls back, the second continues, and a deadlock does not occur. Durch das Verwenden von gespeicherten Prozeduren für alle Datenänderungen kann die Reihenfolge, in der auf Objekte zugegriffen wird, standardisiert werden.Using stored procedures for all data modifications can standardize the order of accessing objects.

deadlock2

Vermeiden von Benutzerinteraktion in TransaktionenAvoid user interaction in Transactions

Vermeiden Sie es, Transaktionen zu schreiben, die Benutzerinteraktionen enthalten, da die Geschwindigkeit von Batches, die ohne Benutzereingriffe ausgeführt werden, bedeutend höher ist als die Geschwindigkeit, mit der ein Benutzer manuell auf Abfragen reagieren muss (z. B. beim Antworten auf eine Eingabeaufforderung, wenn eine Anwendung einen Parameter anfordert).Avoid writing transactions that include user interaction, because the speed of batches running without user intervention is much faster than the speed at which a user must manually respond to queries, such as replying to a prompt for a parameter requested by an application. Wenn eine Transaktion z. B. auf eine Benutzereingabe wartet, der jeweilige Benutzer jedoch zum Essen oder sogar für das Wochenende nach Hause geht, verzögert der Benutzer die Fertigstellung der Transaktion.For example, if a transaction is waiting for user input and the user goes to lunch or even home for the weekend, the user delays the transaction from completing. Dadurch wird der Durchsatz des Systems beeinträchtigt, da Sperren, die von der Transaktion aufrechterhalten werden, erst dann aufgehoben werden, wenn ein Commit oder Rollback für die Transaktion ausgeführt wird.This degrades system throughput because any locks held by the transaction are released only when the transaction is committed or rolled back. Selbst wenn es nicht zu einem Deadlock kommt, werden andere Transaktionen blockiert, die auf dieselben Ressourcen zugreifen, da sie darauf warten, dass die Transaktion beendet wird.Even if a deadlock situation does not arise, other transactions accessing the same resources are blocked while waiting for the transaction to complete.

Verwenden kurzer Transaktionen in einem einzigen BatchKeep Transactions short and in one batch

Ein Deadlock tritt in der Regel dann auf, wenn mehrere Transaktionen mit langer Ausführungszeit gleichzeitig in derselben Datenbank ausgeführt werden.A deadlock typically occurs when several long-running transactions execute concurrently in the same database. Je länger die Transaktion dauert, desto länger werden die exklusiven Sperren oder Updatesperren aufrechterhalten, wodurch andere Aktivitäten blockiert werden und es möglicherweise zu Deadlocks kommt.The longer the transaction, the longer the exclusive or update locks are held, blocking other activity and leading to possible deadlock situations.

Wenn die Transaktionen in einem einzigen Batch enthalten sind, wird die Anzahl der Netzwerkroundtrips während einer Transaktion minimiert, wodurch mögliche Verzögerungen beim Beenden der Transaktion und Aufheben der Sperren reduziert werden.Keeping transactions in one batch minimizes network roundtrips during a transaction, reducing possible delays in completing the transaction and releasing locks.

Verwenden einer niedrigeren IsolationsstufeUse a lower Isolation Level

Ermitteln Sie, ob eine Transaktion auf einer niedrigeren Isolationsstufe ausgeführt werden kann.Determine whether a transaction can run at a lower isolation level. Durch die READ COMMITTED-Implementierung kann eine Transaktion Daten, die zuvor von einer anderen Transaktion gelesen (nicht geändert) wurden, lesen, ohne warten zu müssen, bis die erste Transaktion abgeschlossen ist.Implementing read committed allows a transaction to read data previously read (not modified) by another transaction without waiting for the first transaction to complete. Wenn eine niedrigere Isolationsstufe verwendet wird, beispielsweise READ COMMITTED, werden freigegebene Sperren kürzer aufrechterhalten als bei einer höheren Isolationsstufe, beispielsweise der serialisierbaren.Using a lower isolation level, such as read committed, holds shared locks for a shorter duration than a higher isolation level, such as serializable. Hierdurch werden Sperrkonflikte reduziert.This reduces locking contention.

Verwenden einer auf der Zeilenversionsverwaltung basierenden IsolationsstufeUse a Row Versioning-based Isolation Level

Wenn die Datenbankoption READ_COMMITTED_SNAPSHOT auf ON festgelegt ist, verwendet eine Transaktion, die gemäß der READ COMMITTED-Isolationsstufe ausgeführt wird, bei Lesevorgängen die Zeilenversionsverwaltung anstelle freigegebener Sperren.When the READ_COMMITTED_SNAPSHOT database option is set ON, a transaction running under read committed isolation level uses row versioning rather than shared locks during read operations.

Hinweis

Einige Anwendungen sind auf das Sperr- und Blockierverhalten der READ COMMITTED-Isolation angewiesen.Some applications rely upon locking and blocking behavior of read committed isolation. Für diese Anwendungen sind Änderungen erforderlich, bevor diese Option aktiviert werden kann.For these applications, some change is required before this option can be enabled.

Die Momentaufnahmeisolation verwendet auch die Zeilenversionsverwaltung, die bei Lesevorgängen keine freigegebenen Sperren verwenden.Snapshot isolation also uses row versioning, which does not use shared locks during read operations. Bevor eine Transaktion gemäß der Momentaufnahmeisolation ausgeführt werden kann, muss die Datenbankoption ALLOW_SNAPSHOT_ISOLATION auf ON festgelegt werden.Before a transaction can run under snapshot isolation, the ALLOW_SNAPSHOT_ISOLATION database option must be set ON.

Implementieren Sie diese Isolationsstufen, um die Wahrscheinlichkeit von Deadlocks zu minimieren, die zwischen Lese- und Schreibvorgängen auftreten können.Implement these isolation levels to minimize deadlocks that can occur between read and write operations.

Verwenden gebundener VerbindungenUse bound connections

Beim Verwenden gebundener Verbindungen können zwei oder mehr Verbindungen, die von derselben Anwendung geöffnet wurden, zusammenarbeiten.Using bound connections, two or more connections opened by the same application can cooperate with each other. Sperren, die von den sekundären Verbindungen eingerichtet wurden, werden so aufrechterhalten, als ob sie von der primären Verbindung eingerichtet wurden, und umgekehrt.Any locks acquired by the secondary connections are held as if they were acquired by the primary connection, and vice versa. Folglich blockieren sie sich nicht gegenseitig.Therefore they do not block each other.

SperrenpartitionierungLock Partitioning

In großen Computersystemen können Sperren für häufig referenzierte Objekte einen Leistungsengpass darstellen, weil die Anforderung und Freigabe von Sperren zu Konflikten bei den internen Sperrenressourcen führt.For large computer systems, locks on frequently referenced objects can become a performance bottleneck as acquiring and releasing locks place contention on internal locking resources. Die Sperrenpartitionierung verbessert die Sperrenleistung, indem eine einzelne Sperrenressource in mehrere Sperrenressourcen aufgeteilt wird.Lock partitioning enhances locking performance by splitting a single lock resource into multiple lock resources. Diese Funktion ist nur für Systeme mit 16 oder mehr CPUs verfügbar, wird automatisch aktiviert und kann nicht deaktiviert werden.This feature is only available for systems with 16 or more CPUs, and is automatically enabled and cannot be disabled. Es können nur Objektsperren partitioniert werden. Objektsperren mit einem Untertyp werden nicht partitioniert.Only object locks can be partitioned.Object locks that have a subtype are not partitioned. Weitere Informationen finden Sie unter sys.dm_tran_locks (Transact-SQL).For more information, see sys.dm_tran_locks (Transact-SQL).

Grundlegendes zur SperrenpartitionierungUnderstanding Lock Partitioning

Sperrtasks greifen auf verschiedene freigegebene Ressourcen zu, von denen zwei durch die Sperrenpartitionierung optimiert werden:Locking tasks access several shared resources, two of which are optimized by lock partitioning:

  • Spinlock:Spinlock. Diese Ressource steuert den Zugriff auf eine Sperrenressource wie z. B. eine Zeile oder Tabelle.This controls access to a lock resource, such as a row or a table.

    Ohne die Sperrenpartitionierung verwaltet ein Spinlock alle Sperrenanforderungen für eine einzelne Sperrenressource.Without lock partitioning, one spinlock manages all lock requests for a single lock resource. Bei Systemen mit umfangreicher Aktivität kann es zu Konflikten kommen, wenn Sperrenanforderungen darauf warten, dass das Spinlock verfügbar wird.On systems that experience a large volume of activity, contention can occur as lock requests wait for the spinlock to become available. Unter diesen Umständen kann die Anforderung von Sperren zu einem Engpass werden und sich negativ auf die Leistung auswirken.Under this situation, acquiring locks can become a bottleneck and can negatively impact performance.

    Um Konflikte bei einer einzelnen Sperrenressource zu verringern, teilt die Sperrenpartitionierung eine einzelne Sperrenressource in mehrere Sperrenressourcen auf, um die Auslastung auf mehrere Spinlocks zu verteilen.To reduce contention on a single lock resource, lock partitioning splits a single lock resource into multiple lock resources to distribute the load across multiple spinlocks.

  • SpeicherMemory. Wird zum Speichern der Strukturen von Sperrenressourcen verwendet.This is used to store the lock resource structures.

    Sobald das Spinlock aktiviert wurde, werden die Sperrenstrukturen im Arbeitsspeicher gespeichert, und anschließend erfolgt der Zugriff auf diese Strukturen, und sie werden möglicherweise geändert.Once the spinlock is acquired, lock structures are stored in memory and then accessed and possibly modified. Die Verteilung des Sperrenzugriffs auf mehrere Ressourcen senkt die Notwendigkeit zur Übertragung von Arbeitsspeicherblöcken zwischen CPUs, was zu einer verbesserten Leistung führt.Distributing lock access across multiple resources helps to eliminate the need to transfer memory blocks between CPUs, which will help to improve performance.

Implementieren und Überwachen der SperrenpartitionierungImplementing and Monitoring Lock Partitioning

Die Sperrenpartitionierung wird bei Systemen mit mindestens 16 CPUs standardmäßig aktiviert.Lock partitioning is turned on by default for systems with 16 or more CPUs. Wenn die Sperrenpartitionierung aktiviert ist, wird eine Informationsmeldung im SQL ServerSQL Server-Fehlerprotokoll gespeichert.When lock partitioning is enabled, an informational message is recorded in the SQL ServerSQL Server error log.

Beim Aktivieren von Sperren für eine partitionierte Ressource gelten folgende Grundsätze:When acquiring locks on a partitioned resource:

  • Für eine einzelne Partition werden nur die Sperrmodi NL, SCH-S, IS, IU und IX aktiviert.Only NL, SCH-S, IS, IU, and IX lock modes are acquired on a single partition.

  • Freigegebene Sperren (S), exklusive Sperren (X) und andere Sperren in anderen Modi als NL, SCH-S, IS, IU und IX müssen für alle Partitionen aktiviert werden, beginnend mit der Partitions-ID 0 und nachfolgend in der Partitions-ID-Reihenfolge.Shared (S), exclusive (X), and other locks in modes other than NL, SCH-S, IS, IU, and IX must be acquired on all partitions starting with partition ID 0 and following in partition ID order. Diese Sperren für eine partitionierte Ressource beanspruchen mehr Arbeitsspeicher als Sperren im selben Modus für eine nicht partitionierte Ressource, weil jede Partition effektiv eine separate Sperre ist.These locks on a partitioned resource will use more memory than locks in the same mode on a non-partitioned resource since each partition is effectively a separate lock. Der erhöhte Arbeitsspeicherbedarf richtet sich nach der Anzahl der Partitionen.The memory increase is determined by the number of partitions. Die Sperren-Leistungsindikatoren von SQL ServerSQL Server im Windows-Systemmonitor zeigen Informationen zum Arbeitsspeicher an, der von partitionierten und nicht partitionierten Sperren verwendet wird.The SQL ServerSQL Server lock counters in the Windows Performance Monitor will display information about memory used by partitioned and non-partitioned locks.

Beim Start einer Transaktion wird der Transaktion eine Partition zugewiesen.A transaction is assigned to a partition when the transaction starts. Bei der Transaktion verwenden alle Sperranforderungen, die partitioniert werden können, die der Transaktion zugewiesene Partition.For the transaction, all lock requests that can be partitioned use the partition assigned to that transaction. Durch diese Methode wird der Zugriff auf Sperrenressourcen desselben Objekts durch unterschiedliche Transaktionen auf verschiedene Partitionen verteilt.By this method, access to lock resources of the same object by different transactions is distributed across different partitions.

Die resource_lock_partition-Spalte in der dynamischen Verwaltungssicht (DMV, Dynamic Management View) von sys.dm_tran_locks stellt die Sperrenpartitions-ID für eine sperrenpartitionierte Ressource bereit.The resource_lock_partition column in the sys.dm_tran_locks Dynamic Management View provides the lock partition ID for a lock partitioned resource. Weitere Informationen finden Sie unter sys.dm_tran_locks (Transact-SQL).For more information, see sys.dm_tran_locks (Transact-SQL).

Arbeiten mit der SperrenpartitionierungWorking with Lock Partitioning

Die folgenden Codebeispiele veranschaulichen die Verwendung der Sperrenpartitionierung.The following code examples illustrate lock partitioning. In den Beispielen werden zwei Transaktionen in zwei verschiedenen Sitzungen ausgeführt, um das Verhalten der Sperrenpartitionierung in einem Computersystem mit 16 CPUs zu zeigen.In the examples, two transactions are executed in two different sessions in order to show lock partitioning behavior on a computer system with 16 CPUs.

Mit diesen Transact-SQLTransact-SQL-Anweisungen werden Testobjekte erstellt, die in den folgenden Beispielen verwendet werden.These Transact-SQLTransact-SQL statements create test objects that are used in the examples that follow.

-- Create a test table.  
CREATE TABLE TestTable  (col1 int);  
GO  
  
-- Create a clustered index on the table.  
CREATE CLUSTERED INDEX ci_TestTable   
    ON TestTable (col1);  
GO  
  
-- Populate the table.  
INSERT INTO TestTable VALUES (1);  
GO  

Beispiel AExample A

Sitzung 1Session 1:

Im Rahmen einer Transaktion wird eine SELECT-Anweisung ausgeführt.A SELECT statement is executed under a transaction. Aufgrund des HOLDLOCK-Sperrhinweises aktiviert und hält diese Anweisung eine beabsichtigte freigegebene Sperre für die Tabelle (in dieser Veranschaulichung werden Zeilen- und Seitensperren ignoriert).Because of the HOLDLOCK lock hint, this statement will acquire and retain an Intent shared (IS) lock on the table (for this illustration, row and page locks are ignored). Die beabsichtigte freigegebene Sperre wird nur für die Partition aktiviert, die der Transaktion zugewiesen ist.The IS lock will be acquired only on the partition assigned to the transaction. In diesem Beispiel wird vorausgesetzt, dass die beabsichtigte freigegebene Sperre für die Partitions-ID 7 aktiviert wird.For this example, it is assumed that the IS lock is acquired on partition ID 7.

-- Start a transaction.  
BEGIN TRANSACTION  
    -- This SELECT statement will acquire an IS lock on the table.  
    SELECT col1  
    FROM TestTable  
    WITH (HOLDLOCK);  

Sitzung 2:Session 2:

Eine Transaktion wird gestartet, und die im Rahmen dieser Transaktion ausgeführte SELECT-Anweisung aktiviert und hält eine freigegebene Sperre (S) für die Tabelle.A transaction is started, and the SELECT statement running under this transaction will acquire and retain a shared (S) lock on the table. Die S-Sperre wird für alle Partitionen aktiviert, was mehrere Tabellensperren ergibt, und zwar eine für jede Partition.The S lock will be acquired on all partitions which results in multiple table locks, one for each partition. Auf einem System mit 16 CPUs werden z. B. 16 S-Sperren für die Sperrpartitions-IDs 0 bis 15 aktiviert.For example, on a 16-cpu system, 16 S locks will be issued across lock partition IDs 0-15. Da die S-Sperre mit der beabsichtigten freigegebenen Sperre kompatibel ist, die von der Transaktion in Sitzung 1 für die Partitions-ID 7 gehalten wird, kommt es zu keiner Blockierung zwischen den Transaktionen.Because the S lock is compatible with the IS lock being held on partition ID 7 by the transaction in session 1, there is no blocking between transactions.

BEGIN TRANSACTION  
    SELECT col1  
    FROM TestTable  
    WITH (TABLOCK, HOLDLOCK);  

Sitzung 1Session 1:

Die folgende SELECT-Anweisung wird unter der Transaktion ausgeführt, die unter Sitzung 1 immer noch aktiv ist.The following SELECT statement is executed under the transaction that is still active under session 1. Aufgrund des exklusiven (X) Tabellenblockhinweises versucht die Transaktion, eine X-Sperre für die Tabelle zu aktivieren.Because of the exclusive (X) table lock hint, the transaction will attempt to acquire an X lock on the table. Allerdings blockiert die S-Sperre, die durch die Transaktion in Sitzung 2 gehalten wird, die X-Sperre für die Partitions-ID 0.However, the S lock that is being held by the transaction in session 2 will block the X lock at partition ID 0.

SELECT col1  
FROM TestTable  
WITH (TABLOCKX);  

Beispiel BExample B

Sitzung 1Session 1:

Im Rahmen einer Transaktion wird eine SELECT-Anweisung ausgeführt.A SELECT statement is executed under a transaction. Aufgrund des HOLDLOCK-Sperrhinweises aktiviert und hält diese Anweisung eine beabsichtigte freigegebene Sperre für die Tabelle (in dieser Veranschaulichung werden Zeilen- und Seitensperren ignoriert).Because of the HOLDLOCK lock hint, this statement will acquire and retain an Intent shared (IS) lock on the table (for this illustration, row and page locks are ignored). Die beabsichtigte freigegebene Sperre wird nur für die Partition aktiviert, die der Transaktion zugewiesen ist.The IS lock will be acquired only on the partition assigned to the transaction. In diesem Beispiel wird vorausgesetzt, dass die beabsichtigte freigegebene Sperre für die Partitions-ID 6 aktiviert wird.For this example, it is assumed that the IS lock is acquired on partition ID 6.

-- Start a transaction.  
BEGIN TRANSACTION  
    -- This SELECT statement will acquire an IS lock on the table.  
    SELECT col1  
    FROM TestTable  
    WITH (HOLDLOCK);  

Sitzung 2:Session 2:

Im Rahmen einer Transaktion wird eine SELECT-Anweisung ausgeführt.A SELECT statement is executed under a transaction. Aufgrund des TABLOCKX-Sperrhinweises versucht die Transaktion, eine exklusive Sperre (X) für die Tabelle zu aktivieren.Because of the TABLOCKX lock hint, the transaction tries to acquire an exclusive (X) lock on the table. Denken Sie daran, dass die X-Sperre für alle Partitionen beginnend mit der Partitions-ID 0 aktiviert werden muss.Remember that the X lock must be acquired on all partitions starting with partition ID 0. Die X-Sperre wird für alle Partitions-IDs von 0 bis 5 aktiviert, sie wird jedoch von der für Partitions-ID 6 aktivierten Sperre blockiert.The X lock will be acquired on all partitions IDs 0-5 but will be blocked by the IS lock that is acquired on partition ID 6.

Für die Partitions-IDs 7 bis 15, die die X-Sperre noch nicht erreicht hat, können andere Transaktionen weiterhin Sperren aktivieren.On partition IDs 7-15 that the X lock has not yet reached, other transactions can continue to acquire locks.

BEGIN TRANSACTION  
    SELECT col1  
    FROM TestTable  
    WITH (TABLOCKX, HOLDLOCK);  

Auf Zeilenversionsverwaltung basierende Isolationsstufen im SQL Server-Datenbank-EngineSQL Server Database EngineRow Versioning-based Isolation Levels in the SQL Server-Datenbank-EngineSQL Server Database Engine

Ab SQL Server 2005 (9.x)SQL Server 2005 (9.x) führt das SQL Server-Datenbank-EngineSQL Server Database Engine eine Implementierung der vorhandenen Transaktionsisolationsstufe READ COMMITTED ein, die mithilfe der Zeilenversionsverwaltung eine Momentaufnahme auf Anweisungsebene bereitstellt.Starting with SQL Server 2005 (9.x)SQL Server 2005 (9.x), the SQL Server-Datenbank-EngineSQL Server Database Engine offers an implementation of an existing transaction isolation level, read committed, that provides a statement level snapshot using row versioning. Das SQL Server-Datenbank-EngineSQL Server Database Engine bietet außerdem die Transaktionsisolationsstufe SNAPSHOT, die ebenfalls die Zeilenversionsverwaltung verwendet, um Momentaufnahmen auf Transaktionsebene bereitzustellen.SQL Server-Datenbank-EngineSQL Server Database Engine also offers a transaction isolation level, snapshot, that provides a transaction level snapshot also using row versioning.

Die Zeilenversionsverwaltung ist ein allgemeines Framework in SQL ServerSQL Server, das beim Ändern oder Löschen einer Zeile einen "Kopie-bei-Schreibvorgang"-Mechanismus aufruft.Row versioning is a general framework in SQL ServerSQL Server that invokes a copy-on-write mechanism when a row is modified or deleted. Das setzt bei einer ausgeführten Transaktion voraus, dass die alte Zeilenversion für Transaktionen verfügbar sein muss, die einen früheren transaktionskonsistenten Zustand erfordern.This requires that while the transaction is running, the old version of the row must be available for transactions that require an earlier transactionally consistent state. Die Zeilenversionsverwaltung wird zur Unterstützung folgender Funktionen verwendet:Row versioning is used to do the following:

  • Erstellen der inserted- und deleted-Tabellen in Triggern.Build the inserted and deleted tables in triggers. Für alle durch den Trigger geänderten Zeilen wird die Versionsverwaltung verwendet.Any rows modified by the trigger are versioned. Das schließt die Zeilen ein, die durch die Anweisung geändert wurden, mit der der Start des Triggers erfolgte, sowie alle vom Trigger bewirkten Datenänderungen.This includes the rows modified by the statement that launched the trigger, as well as any data modifications made by the trigger.
  • Unterstützen von Multiple Active Result Sets (MARS).Support Multiple Active Result Sets (MARS). Wenn eine MARS-Sitzung eine Datenänderungsanweisung (z.B. INSERT, UPDATE oder DELETE) ausgibt, während es ein aktives Resultset gibt, wird für die von der Änderungsanweisung betroffenen Zeilen die Versionsverwaltung verwendet.If a MARS session issues a data modification statement (such as INSERT, UPDATE, or DELETE) at a time there is an active result set, the rows affected by the modification statement are versioned.
  • Unterstützen von Indexvorgängen, die die ONLINE-Option angeben.Support index operations that specify the ONLINE option.
  • Unterstützen von auf der Zeilenversionsverwaltung basierenden Transaktionsisolationsstufen:Support row versioning-based transaction isolation levels:
    • Eine neue Implementierung der Read Committed-Isolationsstufe, die die Zeilenversionsverwaltung verwendet, um die Lesekonsistenz auf Anweisungsebene zu gewährleisten.A new implementation of read committed isolation level that uses row versioning to provide statement-level read consistency.
    • Eine neue Isolationsstufe – Momentaufnahme, um die Lesekonsistenz auf der Transaktionsebene zu gewährleisten.A new isolation level, snapshot, to provide transaction-level read consistency.

Die tempdb-Datenbank muss über ausreichend Speicherplatz verfügen, um die Versionen speichern zu können.The tempdb database must have enough space for the version store. Wenn tempdb voll ist, brechen Updatevorgänge die Versionsverwaltung ab und können fortgesetzt werden. Lesevorgänge können hingegen einen Fehler erzeugen, weil eine bestimmte Zeilenversion, die benötigt wird, nicht mehr vorhanden ist.When tempdb is full, update operations will stop generating versions and continue to succeed, but read operations might fail because a particular row version that is needed no longer exists. Das wirkt sich auf Vorgänge wie Trigger, MARS und Onlineindizierung aus.This affects operations like triggers, MARS, and online indexing.

Das Verwenden der Zeilenversionsverwaltung für Read Committed- und Momentaufnahme-Transaktionen umfasst zwei Schritte:Using row versioning for read-committed and snapshot transactions is a two-step process:

  1. Festlegen von einer oder beider Datenbankoptionen READ_COMMITTED_SNAPSHOT und ALLOW_SNAPSHOT_ISOLATION auf ON.Set either or both the READ_COMMITTED_SNAPSHOT and ALLOW_SNAPSHOT_ISOLATION database options ON.

  2. Festlegen der entsprechenden Transaktionsisolationsstufe in einer Anwendung:Set the appropriate transaction isolation level in an application:

    • Wenn die READ_COMMITTED_SNAPSHOT-Datenbankoption auf ON gesetzt ist, verwenden Transaktionen, die die Read Committed-Isolationsstufe festlegen, die Zeilenversionsverwaltung.When the READ_COMMITTED_SNAPSHOT database option is ON, transactions setting the read committed isolation level use row versioning.
    • Wenn die ALLOW_SNAPSHOT_ISOLATION-Datenbankoption auf ON gesetzt ist, können Transaktionen die Momentaufnahme-Isolationsstufe festlegen.When the ALLOW_SNAPSHOT_ISOLATION database option is ON, transactions can set the snapshot isolation level.

Wenn eine der beiden Datenbankoptionen READ_COMMITTED_SNAPSHOT oder ALLOW_SNAPSHOT_ISOLATION auf ON gesetzt ist, weist das SQL Server-Datenbank-EngineSQL Server Database Engine jeder Transaktion, die Daten bearbeitet, mithilfe der Zeilenversionsverwaltung eine Transaktionssequenznummer (XSN, Transaction Sequence Number) zu.When either READ_COMMITTED_SNAPSHOT or ALLOW_SNAPSHOT_ISOLATION database option is set ON, the SQL Server-Datenbank-EngineSQL Server Database Engine assigns a transaction sequence number (XSN) to each transaction that manipulates data using row versioning. Die Transaktionen starten zu dem Zeitpunkt, wenn eine BEGIN TRANSACTION-Anweisung ausgeführt wird.Transactions start at the time a BEGIN TRANSACTION statement is executed. Allerdings startet die Transaktionssequenznummer mit dem ersten Lese- oder Schreibvorgang nach der BEGIN TRANSACTION-Anweisung.However, the transaction sequence number starts with the first read or write operation after the BEGIN TRANSACTION statement. Die Transaktionssequenznummer wird bei jeder Zuweisung um eins erhöht.The transaction sequence number is incremented by one each time it is assigned.

Wenn entweder die Datenbankoption READ_COMMITTED_SNAPSHOT oder ALLOW_SNAPSHOT_ISOLATION auf ON gesetzt ist, werden logische Kopien (Versionen) für alle in der Datenbank erfolgten Datenänderungen aufbewahrt.When either the READ_COMMITTED_SNAPSHOT or ALLOW_SNAPSHOT_ISOLATION database options are ON, logical copies (versions) are maintained for all data modifications performed in the database. Jedes Mal, wenn eine Zeile durch eine bestimmte Transaktion geändert wird, speichert die Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine eine Version des zuvor durch ein Commit bestätigten Images der Zeile in tempdb.Every time a row is modified by a specific transaction, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine stores a version of the previously committed image of the row in tempdb. Jede Version wird mit der Transaktionssequenznummer der Transaktion markiert, von der die Änderung vorgenommen wurde.Each version is marked with the transaction sequence number of the transaction that made the change. Die Versionen der geänderten Zeilen werden mithilfe einer Linkliste verkettet.The versions of modified rows are chained using a link list. Der neueste Zeilenwert wird immer in der aktuellen Datenbank gespeichert und mit den im Versionsspeicher von tempdb gespeicherten Zeilenversionen verkettet.The newest row value is always stored in the current database and chained to the versioned rows stored in tempdb.

Hinweis

Beim Ändern großer Objekte (LOBs, Large Objects) wird nur das geänderte Fragment in den Versionsspeicher in tempdb kopiert.For modification of large objects (LOBs), only the changed fragment is copied to the version store in tempdb.

Die Zeilenversionen werden lang genug aufbewahrt, um den Anforderungen von Transaktionen gerecht zu werden, die unter auf der Zeilenversionsverwaltung basierenden Isolationsstufen ausgeführt werden.Row versions are held long enough to satisfy the requirements of transactions running under row versioning-based isolation levels. SQL Server-Datenbank-EngineSQL Server Database Engine verfolgt die früheste nützliche Transaktionssequenznummer und löscht in regelmäßigen Abständen alle Zeilenversionen, die mit Transaktionssequenznummern versehen sind, die unterhalb der frühesten nützlichen Sequenznummer liegen.The SQL Server-Datenbank-EngineSQL Server Database Engine tracks the earliest useful transaction sequence number and periodically deletes all row versions stamped with transaction sequence numbers that are lower than the earliest useful sequence number.

Wenn beide Datenbankoptionen auf OFF gesetzt sind, werden nur die durch Trigger oder MARS-Sitzungen geänderten Zeilen oder die durch ONLINE-Indizierungsvorgänge gelesenen Zeilen in die Versionsverwaltung einbezogen.When both database options are set to OFF, only rows modified by triggers or MARS sessions, or read by ONLINE index operations, are versioned. Diese Zeilenversionen werden jedoch freigegeben, sobald sie nicht mehr benötigt werden.Those row versions are released when no longer needed. Ein im Hintergrund ausgeführter Thread entfernt in regelmäßigen Abständen alle veralteten Zeilenversionen.A background thread periodically executes to remove stale row versions.

Hinweis

Für Transaktionen von kurzer Dauer kann eine Version einer geänderten Zeile im Pufferpool zwischengespeichert werden, ohne dass sie in die Datenträgerdateien der tempdb-Datenbank geschrieben wird.For short-running transactions, a version of a modified row may get cached in the buffer pool without getting written into the disk files of the tempdb database. Wenn nur ein kurzfristiger Bedarf für die versionsverwaltete Zeile besteht, wird sie einfach aus dem Pufferpool gelöscht und verursacht dadurch nicht unbedingt E/A-Aufwand.If the need for the versioned row is short-lived, it will simply get dropped from the buffer pool and may not necessarily incur I/O overhead.

Verhalten beim Lesen von DatenBehavior when reading data

Wenn unter auf der Zeilenversionsverwaltung basierenden Isolationsstufen ausgeführte Transaktionen Daten lesen, fordern sie keine freigegebenen Sperren (S) für die gelesenen Daten an und blockieren deshalb keine Transaktionen, bei denen Daten geändert werden.When transactions running under row versioning-based isolation read data, the read operations do not acquire shared (S) locks on the data being read, and therefore do not block transactions that are modifying data. Außerdem wird der Aufwand für das Sperren von Ressourcen minimiert, weil nur eine reduzierte Anzahl von Sperren angefordert wird.Also, the overhead of locking resources is minimized as the number of locks acquired is reduced. Die Read Committed-Isolation mit Zeilenversionsverwaltung und die Momentaufnahmeisolation wurden entwickelt, um die Lesekonsistenz der versionsbasierten Daten auf Anweisungsebene bzw. auf Transaktionsebene zu gewährleisten.Read committed isolation using row versioning and snapshot isolation are designed to provide statement-level or transaction-level read consistencies of versioned data.

Alle Abfragen, einschließlich Transaktionen, die in auf der Zeilenversionsverwaltung basierenden Isolationsstufen ausgeführt werden, richten Sperren vom Typ Sch-S (Schemastabilität) während der Kompilierung und der Ausführung ein.All queries, including transactions running under row versioning-based isolation levels, acquire Sch-S (schema stability) locks during compilation and execution. Daher werden Abfragen gesperrt, wenn eine gleichzeitige Transaktion eine Schemaänderungssperre (Sch-M) für die Tabelle aufrechterhält.Because of this, queries are blocked when a concurrent transaction holds a Sch-M (schema modification) lock on the table. Beispielsweise aktiviert ein DDL-Vorgang (Data Definition Language, Datendefinitionssprache) eine Sch-S-Sperre, bevor die Schemainformationen für die Tabelle geändert werden.For example, a data definition language (DDL) operation acquires a Sch-M lock before it modifies the schema information of the table. Abfragetransaktionen, einschließlich der Transaktionen, die eine auf der Zeilenversionsverwaltung basierende Isolationsstufe verwenden, werden beim Anfordern einer Sperre vom Typ Sch-S blockiert.Query transactions, including those running under a row versioning-based isolation level, are blocked when attempting to acquire a Sch-S lock. Umgekehrt blockiert eine Abfrage, die eine Sch-S-Sperre aufrechterhält, eine gleichzeitige Transaktion, die versucht, eine Sch-M-Sperre zu errichten.Conversely, a query holding a Sch-S lock blocks a concurrent transaction that attempts to acquire a Sch-M lock.

Wenn eine Transaktion mithilfe der Momentaufnahmeisolationsstufe gestartet wird, zeichnet die Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine alle aktuell aktiven Transaktionen auf.When a transaction using the snapshot isolation level starts, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine records all of the currently active transactions. Wenn die Momentaufnahmetransaktion eine Zeile liest, die über eine Versionskette verfügt, verfolgt SQL Server-Datenbank-EngineSQL Server Database Engine diese Kette und ruft die Zeile dort ab, wo sich die Transaktionssequenznummer befindet:When the snapshot transaction reads a row that has a version chain, the SQL Server-Datenbank-EngineSQL Server Database Engine follows the chain and retrieves the row where the transaction sequence number is:

  • Am nächsten zur Sequenznummer der Momentaufnahmetransaktion, die die Zeile liest, jedoch unterhalb dieser Sequenznummer.Closest to but lower than the sequence number of the snapshot transaction reading the row.

  • Nicht in der Liste der beim Start der Momentaufnahmetransaktion aktiven Transaktionen.Not in the list of the transactions active when the snapshot transaction started.

Die von einer Momentaufnahmetransaktion ausgeführten Lesevorgänge rufen die letzte Version jeder Zeile ab, für die zum Startzeitpunkt der Momentaufnahmetransaktion ein Commit erfolgt war.Read operations performed by a snapshot transaction retrieve the last version of each row that had been committed at the time the snapshot transaction started. Damit wird ein transaktionskonsistente Momentaufnahme der Daten bereitgestellt, wie sie beim Start der Transaktion vorlagen.This provides a transactionally consistent snapshot of the data as it existed at the start of the transaction.

Read Committed-Transaktionen mit Zeilenversionsverwaltung funktionieren auf sehr ähnliche Weise.Read-committed transactions using row versioning operate in much the same way. Der Unterschied besteht darin, dass die Read Committed-Transaktion beim Auswählen der Zeilenversionen nicht ihre eigene Transaktionssequenznummer verwendet.The difference is that the read-committed transaction does not use its own transaction sequence number when choosing row versions. Jedes Mal, wenn eine Anweisung gestartet wird, liest die Read Committed-Transaktion die letzte Transaktionssequenznummer, die für diese Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine ausgegeben wurde.Each time a statement is started, the read-committed transaction reads the latest transaction sequence number issued for that instance of the SQL Server-Datenbank-EngineSQL Server Database Engine. Das ist die Transaktionssequenznummer, die zum Auswählen der richtigen Zeilenversionen für diese Anweisung verwendet wird.This is the transaction sequence number used to select the correct row versions for that statement. Dadurch können Read Committed-Transaktionen eine Momentaufnahme der Daten sehen, wie sie beim Start jeder Anweisung vorgelegen haben.This allows read-committed transactions to see a snapshot of the data as it exists at the start of each statement.

Hinweis

Obwohl Read Committed-Transaktionen mit Zeilenversionsverwaltung eine im Hinblick auf Transaktionen konsistente Sicht der Daten auf Anweisungsebene bereitstellen, bleiben die von diesem Transaktionstyp generierten Zeilenversionen bzw. die Zeilenversionen, auf die dieser Transaktionstyp zugreift, bis zum Ende der Transaktion erhalten.Even though read-committed transactions using row versioning provides a transactionally consistent view of the data at a statement level, row versions generated or accessed by this type of transaction are maintained until the transaction completes.

Verhalten beim Ändern von DatenBehavior when modifying data

In einer Read Committed-Transaktion mit Zeilenversionsverwaltung erfolgt das Auswählen der zu aktualisierenden Zeilen durch Verwenden eines Blockierungsscans, bei dem eine Updatesperre (U) für die Daten beim Lesen der Datenwerte bewirkt wird.In a read-committed transaction using row versioning, the selection of rows to update is done using a blocking scan where an update (U) lock is taken on the data row as data values are read. Das ist dasselbe Verhalten wie bei Read Committed-Transaktionen ohne Zeilenversionsverwaltung.This is the same as a read-committed transaction that does not use row versioning. Wenn die Datenzeile nicht dem Updatekriterium entspricht, wird die Updatesperre für diese Zeile aufgehoben, und die nächste Zeile wird gesperrt und gescannt.If the data row does not meet the update criteria, the update lock is released on that row and the next row is locked and scanned.

Transaktionen, die mit der Momentaufnahmeisolationsstufe ausgeführt werden, verwenden eine optimistische Vorgehensweise bei der Datenänderung, indem Sperren für Daten aktiviert werden, bevor die Änderung vorgenommen wird, damit Einschränkungen erzwungen werden.Transactions running under snapshot isolation take an optimistic approach to data modification by acquiring locks on data before performing the modification only to enforce constraints. Andernfalls werden erst dann Sperren für Daten aktiviert, wenn die Daten geändert werden sollen.Otherwise, locks are not acquired on data until the data is to be modified. Wenn eine Datenzeile dem Updatekriterium entspricht, überprüft die Momentaufnahmetransaktion, dass die Datenzeile nicht durch eine parallele Transaktion geändert wurde, für die nach dem Start der Momentaufnahmetransaktion ein Commit erfolgte.When a data row meets the update criteria, the snapshot transaction verifies that the data row has not been modified by a concurrent transaction that committed after the snapshot transaction began. Wenn die Datenzeile außerhalb der Momentaufnahmetransaktion geändert wurde, tritt ein Updatekonflikt auf, und die Momentaufnahmetransaktion wird beendet.If the data row has been modified outside of the snapshot transaction, an update conflict occurs and the snapshot transaction is terminated. Der Updatekonflikt wird von SQL Server-Datenbank-EngineSQL Server Database Engine behandelt, und es gibt keinerlei Möglichkeit, die Erkennung von Updatekonflikten zu deaktivieren.The update conflict is handled by the SQL Server-Datenbank-EngineSQL Server Database Engine and there is no way to disable the update conflict detection.

Hinweis

Updatevorgänge, die mit der Momentaufnahmeisolationsstufe gestartet werden, werden unter der Read Committed-Isolation ausgeführt, wenn die Momentaufnahmetransaktion auf eines der folgenden Elemente zugreift:Update operations running under snapshot isolation internally execute under read committed isolation when the snapshot transaction accesses any of the following:

Eine Tabelle mit einer FOREIGN KEY-Einschränkung.A table with a FOREIGN KEY constraint.

Eine Tabelle, auf die in der FOREIGN KEY-Einschränkung einer anderen Tabelle verwiesen wird.A table that is referenced in the FOREIGN KEY constraint of another table.

Eine indizierte Sicht, die auf mehrere Tabellen verweist.An indexed view referencing more than one table.

Allerdings wird der Updatevorgang selbst unter diesen Bedingungen fortgesetzt, um zu überprüfen, dass die Daten nicht durch eine andere Transaktion geändert wurden.However, even under these conditions the update operation will continue to verify that the data has not been modified by another transaction. Wenn die Daten durch eine andere Transaktion geändert wurden, erkennt die Momentaufnahmetransaktion einen Updatekonflikt und wird beendet.If data has been modified by another transaction, the snapshot transaction encounters an update conflict and is terminated.

GesamtverhaltenBehavior in summary

In der folgenden Tabelle werden die Unterschiede zwischen der Momentaufnahmeisolation und der Read Committed-Isolation mit Zeilenversionsverwaltung zusammengefasst.The following table summarizes the differences between snapshot isolation and read committed isolation using row versioning.

EigenschaftProperty Read Committed-Isolationsstufe mit ZeilenversionsverwaltungRead-committed isolation level using row versioning MomentaufnahmeisolationsstufeSnapshot isolation level
Die Datenbankoption, die auf ON gesetzt sein muss, um die erforderliche Unterstützung zu aktivieren.The database option that must be set to ON to enable the required support. READ_COMMITTED_SNAPSHOTREAD_COMMITTED_SNAPSHOT ALLOW_SNAPSHOT_ISOLATIONALLOW_SNAPSHOT_ISOLATION
Wie eine Sitzung den speziellen Typ der Zeilenversionsverwaltung anfordert.How a session requests the specific type of row versioning. Verwenden Sie die standardmäßige Read Committed-Isolationsstufe, oder führen Sie die SET TRANSACTION ISOLATION LEVEL-Anweisung aus, um die READ COMMITTED-Isolationsstufe anzugeben.Use the default read-committed isolation level, or run the SET TRANSACTION ISOLATION LEVEL statement to specify the READ COMMITTED isolation level. Das kann nach dem Start der Transaktion durchgeführt werden.This can be done after the transaction starts. Erfordert, dass SET TRANSACTION ISOLATION LEVEL zum Angeben der MOMENTAUFNAHMEN-Isolationsstufe vor dem Start der Transaktion ausgeführt wird.Requires the execution of SET TRANSACTION ISOLATION LEVEL to specify the SNAPSHOT isolation level before the start of the transaction.
Die von den Anweisungen gelesene Datenversion.The version of data read by statements. Alle Daten, für die vor dem Start jeder Anweisung ein Commit erfolgte.All data that was committed before the start of each statement. Alle Daten, für die vor dem Start jeder Transaktion ein Commit erfolgte.All data that was committed before the start of each transaction.
Wie Updates behandelt werden.How updates are handled. Kehrt von den Zeilenversionen zu den tatsächlichen Daten zurück, um die zu aktualisierenden Zeilen auszuwählen, und verwendet Updatesperren für die ausgewählten Datenzeilen.Reverts from row versions to actual data to select rows to update and uses update locks on the data rows selected. Aktiviert exklusive Sperren für die tatsächlichen Datenzeilen, die geändert werden sollen.Acquires exclusive locks on actual data rows to be modified. Keine Erkennung von Updatekonflikten.No update conflict detection. Verwendet die Zeilenversionen zum Auswählen der zu aktualisierenden Zeilen.Uses row versions to select rows to update. Versucht, eine exklusive Sperre für die tatsächliche Datenzeile zu aktivieren, die geändert werden soll. Wenn die Daten durch eine andere Transaktion geändert wurden, tritt ein Updatekonflikt auf, und die Momentaufnahmetransaktion wird beendet.Tries to acquire an exclusive lock on the actual data row to be modified, and if the data has been modified by another transaction, an update conflict occurs and the snapshot transaction is terminated.
Erkennung von Updatekonflikten.Update conflict detection. Keine.None. Integrierte Unterstützung.Integrated support. Kann nicht deaktiviert werden.Cannot be disabled.

Ressourcenverwendung bei der ZeilenversionsverwaltungRow Versioning resource usage

Das Framework für die Zeilenversionsverwaltung unterstützt die folgenden in SQL ServerSQL Server verfügbaren Funktionen:The row versioning framework supports the following features available in SQL ServerSQL Server:

  • TriggerTriggers
  • Multiple Active Results Sets (MARS)Multiple Active Results Sets (MARS)
  • Online-IndizierungOnline indexing

Das Framework für die Zeilenversionsverwaltung unterstützt zudem die folgenden auf der Zeilenversionsverwaltung basierenden Transaktionsisolationsstufen, die standardmäßig nicht aktiviert sind:The row versioning framework also supports the following row versioning-based transaction isolation levels, which by default are not enabled:

  • Wenn für die Datenbankoption READ_COMMITTED_SNAPSHOT der Wert ON festgelegt ist, stellen READ_COMMITTED-Transaktionen bei Verwendung der Zeilenversionsverwaltung eine Lesekonsistenz auf Anweisungsebene bereit.When the READ_COMMITTED_SNAPSHOT database option is ON, READ_COMMITTED transactions provide statement-level read consistency using row versioning.
  • Wenn für die Datenbankoption ALLOW_SNAPSHOT_ISOLATION der Wert ON festgelegt ist, stellen SNAPSHOT-Transaktionen bei Verwendung der Zeilenversionsverwaltung eine Lesekonsistenz auf Transaktionsebene bereit.When the ALLOW_SNAPSHOT_ISOLATION database option is ON, SNAPSHOT transactions provide transaction-level read consistency using row versioning.

Durch die auf der Zeilenversionsverwaltung basierenden Isolationsstufen wird die Anzahl der von der Transaktion abgerufenen Sperren dadurch reduziert, dass keine freigegebenen Sperren für Lesevorgänge verwendet werden.Row versioning-based isolation levels reduce the number of locks acquired by transaction by eliminating the use of shared locks on read operations. Auf diese Weise wird die Systemleistung erhöht, da die Anzahl der für die Verwaltung der Sperren verwendeten Ressourcen reduziert wird.This increases system performance by reducing the resources used to manage locks. Die Leistung wird zudem dadurch erhöht, dass die Anzahl von Sperrungen einer Transaktion durch von anderen Transaktionen angeforderte Sperren verringert wird.Performance is also increased by reducing the number of times a transaction is blocked by locks acquired by other transactions.

Auf der Zeilenversionsverwaltung basierende Isolationsstufen erhöhen die von Datenänderungen benötigten Ressourcen.Row versioning-based isolation levels increase the resources needed by data modifications. Bei Aktivierung dieser Optionen werden für alle Datenänderungen für die Datenbank Versionen angegeben.Enabling these options causes all data modifications for the database to be versioned. Eine Kopie der Daten in dem Zustand vor der Änderung wird in tempdb gespeichert. Dies ist auch dann der Fall, wenn keine aktiven Transaktionen die auf der Zeilenversionsverwaltung basierende Isolation verwenden.A copy of the data before modification is stored in tempdb even when there are no active transactions using row versioning-based isolation. Die Daten nach der Änderung enthalten einen Verweis auf die in tempdb gespeicherten Daten, die über eine Versionsangabe verfügen.The data after modification includes a pointer to the versioned data stored in tempdb. Im Fall von großen Objekten wird nur ein Teil des geänderten Objekts in tempdb gespeichert.For large objects, only part of the object that changed is copied to tempdb.

In tempdb verwendeter SpeicherplatzSpace used in TempDB

tempdb muss für jede Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine über genügend Speicherplatz für die Zeilenversionen verfügen, die für sämtliche Datenbanken in der Instanz generiert wurden.For each instance of the SQL Server-Datenbank-EngineSQL Server Database Engine, tempdb must have enough space to hold the row versions generated for every database in the instance. Der Datenbankadministrator muss sicherstellen, dass tempdb über genügend Speicherplatz verfügt, um den Versionsspeicher zu unterstützen.The database administrator must ensure that TempDB has ample space to support the version store. In tempdb befinden sich zwei Versionsspeicher:There are two version stores in TempDB:

  • Der Onlineindexerstellungs-Versionsspeicher wird für Onlineindexerstellungen in allen Datenbanken verwendet.The online index build version store is used for online index builds in all databases.
  • Der allgemeine Versionsspeicher wird für alle anderen Datenänderungsvorgänge in sämtlichen Datenbanken verwendet.The common version store is used for all other data modification operations in all databases.

Zeilenversionen müssen so lange gespeichert werden, wie eine aktive Transaktion darauf zugreifen muss.Row versions must be stored for as long as an active transaction needs to access it. Einmal pro Minute entfernt ein Hintergrundthread nicht mehr benötigte Zeilenversionen und gibt so Versionsspeicherplatz in tempdb frei.Once every minute, a background thread removes row versions that are no longer needed and frees up the version space in TempDB. Eine Transaktion mit langer Ausführungszeit verhindert, dass der Speicherplatz im Versionsspeicher freigegeben werden kann, wenn sie eine der folgenden Bedingungen erfüllt:A long-running transaction prevents space in the version store from being released if it meets any of the following conditions:

  • Sie verwendet die auf der Zeilenversionsverwaltung basierende Isolation.It uses row versioning-based isolation.
  • Sie verwendet Trigger, MARS oder Onlineindexerstellungs-Vorgänge.It uses triggers, MARS, or online index build operations.
  • Sie generiert Zeilenversionen.It generates row versions.

Hinweis

Wenn innerhalb einer Transaktion ein Trigger aufgerufen wird, werden die vom Trigger generierten Zeilenversionen bis zum Ende der Transaktion beibehalten, auch wenn die Zeilenversionen nach Abschluss des Triggers nicht mehr benötigt werden.When a trigger is invoked inside a transaction, the row versions created by the trigger are maintained until the end of the transaction, even though the row versions are no longer needed after the trigger completes. Dies gilt auch für Read Committed-Transaktionen, die Zeilenversionsverwaltung verwenden.This also applies to read-committed transactions that use row versioning. Bei diesem Transaktionstyp wird nur für die einzelnen Anweisungen in der Transaktion eine im Hinblick auf Transaktionen konsistente Sicht der Datenbank benötigt.With this type of transaction, a transactionally consistent view of the database is needed only for each statement in the transaction. Dies bedeutet, dass die für eine Anweisung in der Transaktion erstellten Zeilenversionen nach Abschluss der Anweisung nicht mehr benötigt werden.This means that the row versions created for a statement in the transaction are no longer needed after the statement completes. Die von den einzelnen Anweisungen in der Transaktion erstellten Zeilenversionen werden jedoch bis zum Abschluss der Transaktion beibehalten.However, row versions created by each statement in the transaction are maintained until the transaction completes.

Wenn tempdb nicht mehr über genügend Speicherplatz verfügt, erzwingt SQL Server-Datenbank-EngineSQL Server Database Engine eine Verkleinerung der Versionsspeicher.When TempDB runs out of space, the SQL Server-Datenbank-EngineSQL Server Database Engine forces the version stores to shrink. Während des Verkleinerungsprozesses werden die Transaktionen mit der längsten Ausführungszeit, die noch keine Zeilenversionen generiert haben, als Opfer gekennzeichnet.During the shrink process, the longest running transactions that have not yet generated row versions are marked as victims. Die Meldung 3967 wird im Fehlerprotokoll für jede Opfertransaktion generiert.A message 3967 is generated in the error log for each victim transaction. Wenn eine Transaktion als Opfer gekennzeichnet ist, kann sie die Zeilenversionen im Versionsspeicher nicht mehr lesen.If a transaction is marked as a victim, it can no longer read the row versions in the version store. Wenn die Transaktion versucht, Zeilenversionen zu lesen, wird die Meldung 3966 generiert, und es wird ein Rollback für die Transaktion ausgeführt.When it attempts to read row versions, message 3966 is generated and the transaction is rolled back. Ist die Verkleinerung des Prozesses erfolgreich, wird Speicherplatz in tempdb verfügbar.If the shrinking process succeeds, space becomes available in tempdb. Anderenfalls ist in tempdb nicht mehr genügend Speicherplatz vorhanden, und folgender Fehler tritt auf:Otherwise, tempdb runs out of space and the following occurs:

  • Schreibvorgänge werden weiterhin ausgeführt, generieren jedoch keine Versionen.Write operations continue to execute but do not generate versions. Eine Informationsmeldung (3959) wird im Fehlerprotokoll angezeigt. Die Transaktion, die Daten schreibt, ist jedoch nicht betroffen.An information message (3959) appears in the error log, but the transaction that writes data is not affected.

  • Transaktionen, die versuchen, auf Zeilenversionen zuzugreifen, die aufgrund eines vollständigen tempdb-Rollbacks nicht generiert wurden, werden beendet, und der Fehler 3958 wird ausgegeben.Transactions that attempt to access row versions that were not generated because of a tempdb full rollback terminate with an error 3958.

In Datenzeilen verwendeter SpeicherplatzSpace used in data rows

Jede Datenbankzeile kann am Ende der Zeile bis zu 14 Byte für Zeilenversionsverwaltungs-Informationen nutzen.Each database row may use up to 14 bytes at the end of the row for row versioning information. Zu den Zeilenversionsverwaltungs-Informationen zählen die Transaktionssequenznummer der Transaktion, die den Commit für die Version ausgeführt hat, sowie der Zeiger auf die Zeile mit Versionsangabe.The row versioning information contains the transaction sequence number of the transaction that committed the version and the pointer to the versioned row. Diese 14 Byte werden hinzugefügt, wenn die Zeile zum ersten Mal geändert wird oder wenn unter einer der folgenden Bedingungen eine neue Zeile eingefügt wird:These 14 bytes are added the first time the row is modified, or when a new row is inserted, under any of these conditions:

  • Die Option READ_COMMITTED_SNAPSHOT oder ALLOW_SNAPSHOT_ISOLATION ist auf ON festgelegt.READ_COMMITTED_SNAPSHOT or ALLOW_SNAPSHOT_ISOLATION options are ON.
  • Die Tabelle verfügt über einen Trigger.The table has a trigger.
  • Multiple Active Results Sets (MARS) wird verwendet.Multiple Active Results Sets (MARS) is being used.
  • Onlineindexerstellungs-Vorgänge werden derzeit für die Tabelle ausgeführt.Online index build operations are currently running on the table.

Diese 14 Byte werden aus der Datenbankzeile entfernt, wenn die Zeile zum ersten Mal unter allen der folgenden Bedingungen geändert wird:These 14 bytes are removed from the database row the first time the row is modified under all of these conditions:

  • Die Optionen READ_COMMITTED_SNAPSHOT und ALLOW_SNAPSHOT_ISOLATION sind auf OFF festgelegt.READ_COMMITTED_SNAPSHOT and ALLOW_SNAPSHOT_ISOLATION options are OFF.
  • Der Trigger ist nicht mehr für die Tabelle vorhanden.The trigger no longer exists on the table.
  • MARS wird nicht verwendet.MARS is not being used.
  • Es werden derzeit keine Onlineindexerstellungs-Vorgänge ausgeführt.Online index build operations are not currently running.

Der Datenbank sollte so viel Speicherplatz zugeordnet werden, dass sie 14 Bytes pro Datenbankzeile aufnehmen kann, falls eine der Funktionen zur Zeilenversionsverwaltung verwendet wird.If you use any of the row versioning features, you might need to allocate additional disk space for the database to accommodate the 14 bytes per database row. Das Hinzufügen von Zeilenversionsverwaltungs-Informationen kann Indexseitenteilungen oder die Zuordnung einer neuen Datenseite zur Folge haben, falls auf der aktuellen Seite nicht genügend Speicherplatz verfügbar ist.Adding the row versioning information can cause index page splits or the allocation of a new data page if there is not enough space available on the current page. Beispiel: Wenn die durchschnittliche Zeilenlänge 100 Bytes beträgt, wächst eine vorhandene Tabelle durch die zusätzlichen 14 Bytes um 14 Prozent.For example, if the average row length is 100 bytes, the additional 14 bytes cause an existing table to grow up to 14 percent.

Durch Verringern des Füllfaktors kann die Fragmentierung der Indexseiten reduziert oder verhindert werden.Decreasing the fill factor might help to prevent or decrease fragmentation of index pages. Zum Anzeigen der Fragmentierungsinformationen für die Daten und Indizes einer Tabelle oder Sicht können Sie sys.dm_db_index_physical_stats verwenden.To view fragmentation information for the data and indexes of a table or view, you can use sys.dm_db_index_physical_stats.

In großen Objekten verwendeter SpeicherplatzSpace used in Large Objects

SQL Server-Datenbank-EngineSQL Server Database Engine unterstützt sechs Datentypen, die lange Zeichenfolgen von bis zu 2 Gigabyte (GB) Länge aufnehmen können: nvarchar(max), varchar(max), varbinary(max), ntext, text und image.The SQL Server-Datenbank-EngineSQL Server Database Engine supports six data types that can hold large strings up to 2 gigabytes (GB) in length: nvarchar(max), varchar(max), varbinary(max), ntext, text, and image. Lange Zeichenfolgen, die mithilfe dieser Datentypen gespeichert werden, werden in einer Reihe von Datenfragmenten gespeichert, die mit der Datenzeile verknüpft sind.Large strings stored using these data types are stored in a series of data fragments that are linked to the data row. Zeilenversionsverwaltungs-Informationen werden in sämtlichen Fragmenten gespeichert, die zum Speichern dieser langen Zeichenfolgen verwendet werden.Row versioning information is stored in each fragment used to store these large strings. Datenfragmente stellen eine Sammlung von Seiten dar, die für große Objekte in einer Tabelle dediziert sind.Data fragments are a collection of pages dedicated to large objects in a table.

Wenn einer Datenbank neue große Werte hinzugefügt werden, werden diese mithilfe von maximal 8.040 Byte an Daten pro Fragment zugeordnet.As new large values are added to a database, they are allocated using a maximum of 8040 bytes of data per fragment. In früheren Versionen von SQL Server-Datenbank-EngineSQL Server Database Engine wurden bis zu 8.080 Byte an ntext-, text- oder image-Daten pro Fragment gespeichert.Earlier versions of the SQL Server-Datenbank-EngineSQL Server Database Engine stored up to 8080 bytes of ntext, text, or image data per fragment.

Vorhandene ntext-, text- und image-Daten großer Objekte (LOB, Large Objects) werden nicht aktualisiert, um Speicherplatz für die Zeilenversionsverwaltungs-Informationen freizugeben, wenn ein Upgrade einer Datenbank von einer früheren Version von SQL ServerSQL Server auf SQL ServerSQL Server durchgeführt wird.Existing ntext, text, and image large object (LOB) data is not updated to make space for the row versioning information when a database is upgraded to SQL ServerSQL Server from an earlier version of SQL ServerSQL Server. Wenn die LOB-Daten jedoch zum ersten Mal geändert werden, wird mit ihnen ein dynamisches Upgrade durchgeführt, um das Speichern von Versionsinformationen zu ermöglichen.However, the first time the LOB data is modified, it is dynamically upgraded to enable storage of versioning information. Dies ist auch dann der Fall, wenn keine Zeilenversionen generiert werden.This will happen even if row versions are not generated. Nachdem ein Upgrade mit den LOB-Daten durchgeführt wurde, wird die maximale Byteanzahl, die pro Fragment gespeichert wird von 8.080 auf 8.040 reduziert.After the LOB data is upgraded, the maximum number of bytes stored per fragment is reduced from 8080 bytes to 8040 bytes. Der Upgradeprozess ist dem Löschen des LOB-Werts und dem erneuten Einsetzen desselben Werts gleichwertig.The upgrade process is equivalent to deleting the LOB value and reinserting the same value. Ein Upgrade der LOB-Daten wird auch dann durchgeführt, wenn nur ein Byte geändert wird.The LOB data is upgraded even if only one byte is modified. Es handelt sich hierbei um einen einmaligen Vorgang für jede ntext-, text-, oder image-Spalte. Durch jeden Vorgang wird jedoch je nach dem Umfang der LOB-Daten eine hohe Menge an Seitenzuordnungen und E/A-Aktivitäten generiert.This is a one-time operation for each ntext, text, or image column, but each operation may generate a large amount of page allocations and I/O activity depending upon the size of the LOB data. Es können zudem viele Protokollierungsaktivitäten generiert werden, sofern die Änderung vollständig protokolliert wird.It may also generate a large amount of logging activity if the modification is fully logged. WRITETEXT- und UPDATETEXT-Vorgänge werden minimal protokolliert, wenn der Datenbankwiederherstellungsmodus auf den Wert FULL festgelegt ist.WRITETEXT and UPDATETEXT operations are minimally logged if database recovery mode is not set to FULL.

Die nvarchar(max)-, varchar(max)- und varbinary(max)-Datentypen sind in früheren Versionen von SQL ServerSQL Server nicht verfügbar.The nvarchar(max), varchar(max), and varbinary(max) data types are not available in earlier versions of SQL ServerSQL Server. Aus diesem Grund weisen sie keine Upgradeprobleme auf.Therefore, they have no upgrade issues.

Es sollte genügend Speicherplatz zugeordnet werden, um dieser Anforderung gerecht zu werden.Enough disk space should be allocated to accommodate this requirement.

Überwachen der Zeilenversionsverwaltung und des VersionsspeichersMonitoring Row Versioning and the Version Store

Für die Überwachung von Zeilenversionsverwaltungs-, Versionsspeicher- und Momentaufnahmeisolationsprozessen in Bezug auf die Leistung und Probleme stellt SQL ServerSQL Server Tools in Form von dynamische Verwaltungssichten (DMVs, Dynamic Management Views) und Leistungsindikatoren im Systemmonitor von Windows zur Verfügung.For monitoring row versioning, version store, and snapshot isolation processes for performance and problems, SQL ServerSQL Server provides tools in the form of Dynamic Management Views (DMVs) and performance counters in Windows System Monitor.

DMVsDMVs

Die folgenden DMVs stellen Informationen zu den aktuellen Systemstatus von tempdb und den Versionsspeicher sowie die Transaktionen bereit, die die Zeilenversionsverwaltung verwenden.The following DMVs provide information about the current system state of tempdb and the version store, as well as transactions using row versioning.

sys.dm_db_file_space_usage.sys.dm_db_file_space_usage. Gibt Informationen zur Speicherverwendung aller Dateien in der Datenbank zurück.Returns space usage information for each file in the database. Weitere Informationen finden Sie unter sys.dm_db_file_space_usage (Transact-SQL).For more information, see sys.dm_db_file_space_usage (Transact-SQL).

sys.dm_db_session_space_usage.sys.dm_db_session_space_usage. Gibt Aktivität für die Seitenzuordnung und die Zuordnungsaufhebung nach Sitzung für die Datenbank zurück.Returns page allocation and deallocation activity by session for the database. Weitere Informationen finden Sie unter sys.dm_db_session_space_usage (Transact-SQL).For more information, see sys.dm_db_session_space_usage (Transact-SQL).

sys.dm_db_task_space_usage.sys.dm_db_task_space_usage. Gibt für die Datenbank Aktivitäten zu Seitenzuordnungen und aufgehobenen Seitenzuordnungen nach Tasks zurück.Returns page allocation and deallocation activity by task for the database. Weitere Informationen finden Sie unter sys.dm_db_task_space_usage (Transact-SQL).For more information, see sys.dm_db_task_space_usage (Transact-SQL).

sys.dm_tran_top_version_generators.sys.dm_tran_top_version_generators. Gibt eine virtuelle Tabelle für die Objekte zurück, die die meisten Versionen im Versionsspeicher erzeugen.Returns a virtual table for the objects producing the most versions in the version store. Hierbei werden die ersten 256 aggregierten Datensatzlängen nach database_id und rowset_id gruppiert.It groups the top 256 aggregated record lengths by database_id and rowset_id. Mithilfe dieser Funktion können Sie die größten Consumer des Versionsspeichers finden.Use this function to find the largest consumers of the version store. Weitere Informationen finden Sie unter sys.dm_tran_top_version_generators (Transact-SQL).For more information, see sys.dm_tran_top_version_generators (Transact-SQL).

sys.dm_tran_version_store.sys.dm_tran_version_store. Gibt eine virtuelle Tabelle zurück, die alle Versionsdatensätze im allgemeinen Versionsspeicher anzeigt.Returns a virtual table that displays all version records in the common version store. Weitere Informationen finden Sie unter sys.dm_tran_version_store (Transact-SQL).For more information, see sys.dm_tran_version_store (Transact-SQL).

sys.dm_tran_version_store_space_usage.sys.dm_tran_version_store_space_usage. Gibt eine virtuelle Tabelle zurück, die den gesamten in „tempdb“ verwendeten Speicherplatz der Versionsspeicherdatensätze für jede Datenbank anzeigt.Returns a virtual table that displays the total space in tempdb used by version store records for each database. Weitere Informationen finden Sie unter sys.dm_tran_version_store_space_usage (Transact-SQL).For more information, see sys.dm_tran_version_store_space_usage (Transact-SQL).

Hinweis

Die Ausführung von sys.dm_tran_top_version_generators und sys.dm_tran_version_store kann sehr teuer sein, da beide Funktionen den gesamten Versionsspeicher abfragen, der möglicherweise sehr groß ist.sys.dm_tran_top_version_generators and sys.dm_tran_version_store are potentially very expensive functions to run, since both query the entire version store, which could be very large.
Die Ausführung von sys.dm_tran_version_store_space_usage ist effizient und nicht teuer, da es nicht durch die einzelnen Versionsspeicherdatensätze navigiert und den in „tempdb“ pro Datenbank verwendeten aggregierten Versionsspeicherplatz zurückgibt.sys.dm_tran_version_store_space_usage is efficient and not expensive to run, as it does not navigate through individual version store records and returns aggregated version store space consumed in tempdb per database

sys.dm_tran_active_snapshot_database_transactions.sys.dm_tran_active_snapshot_database_transactions. Gibt eine virtuelle Tabelle für alle aktiven Transaktionen in sämtlichen Datenbanken in der SQL ServerSQL Server-Instanz zurück, die die Zeilenversionsverwaltung verwenden.Returns a virtual table for all active transactions in all databases within the SQL ServerSQL Server instance that use row versioning. Systemtransaktionen werden in dieser DMV nicht angezeigt.System transactions do not appear in this DMV. Weitere Informationen finden Sie unter sys.dm_tran_active_snapshot_database_transactions (Transact-SQL).For more information, see sys.dm_tran_active_snapshot_database_transactions (Transact-SQL).

sys.dm_tran_transactions_snapshot.sys.dm_tran_transactions_snapshot. Gibt eine virtuelle Tabelle zurück, die Momentaufnahmen anzeigt, die von den einzelnen Transaktionen erstellt wurden.Returns a virtual table that displays snapshots taken by each transaction. Die Momentaufnahme enthält die Sequenznummer der aktiven Transaktionen, die die Zeilenversionsverwaltung verwenden.The snapshot contains the sequence number of the active transactions that use row versioning. Weitere Informationen finden Sie unter sys.dm_tran_transactions_snapshot (Transact-SQL).For more information, see sys.dm_tran_transactions_snapshot (Transact-SQL).

sys.dm_tran_current_transaction.sys.dm_tran_current_transaction. Gibt eine einzelne Zeile zurück, die auf die Zeilenversionsverwaltung bezogene Statusinformationen der Transaktion in der aktuellen Sitzung anzeigt.Returns a single row that displays row versioning-related state information of the transaction in the current session. Weitere Informationen finden Sie unter sys.dm_tran_current_transaction (Transact-SQL).For more information, see sys.dm_tran_current_transaction (Transact-SQL).

sys.dm_tran_current_snapshot.sys.dm_tran_current_snapshot. Gibt eine virtuelle Tabelle zurück, die alle aktiven Transaktionen zum Zeitpunkt des Startens der aktuellen Momentaufnahmeisolation aufführt.Returns a virtual table that displays all active transactions at the time the current snapshot isolation transaction starts. Wenn die aktuelle Transaktion die Momentaufnahmeisolation verwendet, gibt diese Funktion keine Zeilen zurück.If the current transaction is using snapshot isolation, this function returns no rows. sys.dm_tran_current_snapshot ähnelt sys.dm_tran_transactions_snapshot, mit dem Unterschied, dass es nur die aktiven Transaktionen für die aktuelle Momentaufnahme zurückgibt.sys.dm_tran_current_snapshot is similar to sys.dm_tran_transactions_snapshot, except that it returns only the active transactions for the current snapshot. Weitere Informationen finden Sie unter sys.dm_tran_current_snapshot (Transact-SQL).For more information, see sys.dm_tran_current_snapshot (Transact-SQL).

LeistungsindikatorenPerformance Counters

SQL ServerSQL Server-Leistungsindikatoren stellen Informationen zur Auswirkung von SQL ServerSQL Server-Prozessen auf die Systemleistung zur Verfügung.performance counters provide information about the system performance impacted by SQL ServerSQL Server processes. Die folgenden Leistungsindikatoren überwachen tempdb und den Versionsspeicher sowie Transaktionen mithilfe der Zeilenversionsverwaltung.The following performance counters monitor tempdb and the version store, as well as transactions using row versioning. Die Leistungsindikatoren sind im SQLServer:Transaktionen-Leistungsobjekt enthalten.The performance counters are contained in the SQLServer:Transactions performance object.

Freier Speicherplatz in tempdb (KB) :Free Space in tempdb (KB). Überwacht die Menge des freien Speicherplatzes in Kilobyte (KB), der in der tempdb-Datenbank zur Verfügung steht.Monitors the amount, in kilobytes (KB), of free space in the tempdb database. Es muss genügend freier Speicherplatz in tempdb zur Verfügung stehen, um den Versionsspeicher zu bearbeiten, der die Momentaufnahmeisolation unterstützt.There must be enough free space in tempdb to handle the version store that supports snapshot isolation.

Die folgende Formel ermöglicht eine grobe Schätzung der Größe des Versionsspeichers.The following formula provides a rough estimate of the size of the version store. Bei lange andauernden Transaktionen kann es sich als sinnvoll erweisen, die Generierungs- und Cleanuprate zu überwachen, um die maximale Größe des Versionsspeichers einzuschätzen.For long-running transactions, it may be useful to monitor the generation and cleanup rate to estimate the maximum size of the version store.

[size of common version store] = 2 * [version store data generated per minute] * [longest running time (minutes) of the transaction][size of common version store] = 2 * [version store data generated per minute] * [longest running time (minutes) of the transaction]

Die längste Ausführungszeit von Transaktionen sollte Onlineindexerstellungs-Vorgänge nicht einschließen.The longest running time of transactions should not include online index builds. Da diese Vorgänge bei sehr großen Tabellen viel Zeit in Anspruch nehmen können, verwenden Onlineindexerstellungs-Vorgänge einen separaten Versionsspeicher.Because these operations may take a long time on very large tables, online index builds use a separate version store. Die ungefähre Größe des Onlineindexerstellungs-Versionsspeichers entspricht der Menge der in der Tabelle geänderten Daten, einschließlich aller Indizes, während die Onlineindexerstellung aktiviert ist.The approximate size of the online index build version store equals the amount of data modified in the table, including all indexes, while the online index build is active.

Versionsspeichergröße (KB) :Version Store Size (KB). Überwacht die Größe in KB aller Versionsspeicher.Monitors the size in KB of all version stores. Mithilfe dieser Informationen können Sie die Menge des Speicherplatzes bestimmen, die in der tempdb-Datenbank für den Versionsspeicher benötigt wird.This information helps determine the amount of space needed in the tempdb database for the version store. Das Überwachen dieser Indikatoren über einen gewissen Zeitraum ermöglicht eine hilfreiche Schätzung des zusätzlich für tempdb benötigten Speicherplatzes.Monitoring this counter over a period of time provides a useful estimate of additional space needed for tempdb.

Version Generation rate (KB/s).Version Generation rate (KB/s). Überwacht die Versionsgenerierungsrate, in KB pro Sekunde, in allen Versionsspeichern.Monitors the version generation rate in KB per second in all version stores.

Version Cleanup rate (KB/s).Version Cleanup rate (KB/s). Überwacht die Versionscleanuprate, in KB pro Sekunde, in allen Versionsspeichern.Monitors the version cleanup rate in KB per second in all version stores.

Hinweis

Die Informationen aus Versionsgenerierungsrate (KB/s) und Versionscleanuprate (KB/s) können zur Vorhersage von Speicherplatzanforderungen für tempdb verwendet werden.Information from Version Generation rate (KB/s) and Version Cleanup rate (KB/s) can be used to predict tempdb space requirements.

Anzahl der Versionsspeichereinheiten:Version Store unit count. Überwacht die Anzahl der Versionsspeichereinheiten.Monitors the count of version store units.

Erstellen von Versionsspeichereinheiten:Version Store unit creation. Überwacht die Gesamtzahl der Versionsspeichereinheiten, die für das Speichern von Zeilenversionen erstellt wurden, seitdem die Instanz gestartet wurde.Monitors the total number of version store units created to store row versions since the instance was started.

Abschneiden von Versionsspeichereinheiten:Version Store unit truncation. Überwacht die Gesamtzahl der Versionsspeichereinheiten, die abgeschnitten wurden, seitdem die Instanz gestartet wurde.Monitors the total number of version store units truncated since the instance was started. Eine Versionsspeichereinheit wird abgeschnitten, wenn SQL ServerSQL Server bestimmt, dass keine der Versionszeilen, die in der Versionsspeichereinheit gespeichert sind, für die Ausführung aktiver Transaktionen benötigt wird.A version store unit is truncated when SQL ServerSQL Server determines that none of the version rows stored in the version store unit are needed to run active transactions.

Updatekonfliktquote:Update conflict ratio. Überwacht die Quote von Update-Momentaufnahmetransaktionen, die Updatekonflikte aufweisen, im Verhältnis zur Gesamtzahl der Update-Momentaufnahmetransaktionen.Monitors the ratio of update snapshot transaction that have update conflicts to the total number of update snapshot transactions.

Längste Transaktionsausführungszeit:Longest Transaction Running Time. Überwacht die längste Ausführungszeit in Sekunden aller Transaktionen, die die Zeilenversionsverwaltung verwenden.Monitors the longest running time in seconds of any transaction using row versioning. Hiermit kann bestimmt werden, ob eine Transaktion über eine nicht vertretbare Zeitdauer ausgeführt wird.This can be used to determine if any transaction is running for an unreasonable amount of time.

Transaktionen:Transactions. Überwacht die Gesamtzahl aktiver Transaktionen.Monitors the total number of active transactions. Dieser Leistungsindikator schließt keine Systemtransaktionen ein.This does not include system transactions.

Snapshot Transactions.Snapshot Transactions. Überwacht die Gesamtzahl aktiver Momentaufnahmetransaktionen.Monitors the total number of active snapshot transactions.

Update Snapshot Transactions.Update Snapshot Transactions. Überwacht die Gesamtzahl aktiver Momentaufnahmetransaktionen, die Updatevorgänge ausführen.Monitors the total number of active snapshot transactions that perform update operations.

NonSnapshot Version Transactions.NonSnapshot Version Transactions. Überwacht die Gesamtzahl aktiver Nichtmomentaufnahme-Transaktionen, die Versionsdatensätze generieren.Monitors the total number of active non-snapshot transactions that generate version records.

Hinweis

Die Summe von Update-Momentaufnahmetransaktionen und NonSnapshot-Versionstransaktionen stellt die Gesamtzahl der Transaktionen dar, die an der Versionsgenerierung teilnehmen.The sum of Update Snapshot Transactions and NonSnapshot Version Transactions represents the total number of transactions that participate in version generation. Die Differenz zwischen Momentaufnahmetransaktionen und Update-Momentaufnahmetransaktionen gibt die Anzahl der schreibgeschützten Momentaufnahmetransaktionen an.The difference of Snapshot Transactions and Update Snapshot Transactions reports the number of read-only snapshot transactions.

Beispiel für eine auf der Zeilenversionsverwaltung basierende IsolationsstufeRow Versioning-based Isolation Level Example

Die folgenden Beispiele zeigen die Unterschiede im Verhalten zwischen Momentaufnahmeisolationstransaktionen und Transaktionen, bei denen ein Commit vor dem Lesevorgang ausgeführt werden muss, und die die Zeilenversionsverwaltung verwenden.The following examples show the differences in behavior between snapshot isolation transactions and read-committed transactions that use row versioning.

A.A. Arbeiten mit der MomentaufnahmeisolationWorking with snapshot isolation

In diesem Beispiel liest eine Transaktion, die unter Momentaufnahmeisolation ausgeführt wird, Daten, die anschließend von einer anderen Transaktion geändert werden.In this example, a transaction running under snapshot isolation reads data that is then modified by another transaction. Die Momentaufnahmetransaktion blockiert nicht den Updatevorgang, der von der anderen Transaktion ausgeführt wird, liest auch weiterhin Daten aus der versionsspezifischen Zeile und ignoriert die Datenänderung.The snapshot transaction does not block the update operation executed by the other transaction, and it continues to read data from the versioned row, ignoring the data modification. Wenn die Momentaufnahmetransaktion jedoch versucht, die Daten zu ändern, die bereits von der anderen Transaktion geändert wurden, generiert die Momentaufnahmetransaktion einen Fehler und wird beendet.However, when the snapshot transaction attempts to modify the data that has already been modified by the other transaction, the snapshot transaction generates an error and is terminated.

Für Sitzung 1:On session 1:

USE AdventureWorks2016;  
GO  
  
-- Enable snapshot isolation on the database.  
ALTER DATABASE AdventureWorks2016  
    SET ALLOW_SNAPSHOT_ISOLATION ON;  
GO  
  
-- Start a snapshot transaction  
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;  
GO  
  
BEGIN TRANSACTION;  
    -- This SELECT statement will return  
    -- 48 vacation hours for the employee.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 2:On session 2:

USE AdventureWorks2016;  
GO  
  
-- Start a transaction.  
BEGIN TRANSACTION;  
    -- Subtract a vacation day from employee 4.  
    -- Update is not blocked by session 1 since  
    -- under snapshot isolation shared locks are  
    -- not requested.  
    UPDATE HumanResources.Employee  
        SET VacationHours = VacationHours - 8  
        WHERE BusinessEntityID = 4;  
  
    -- Verify that the employee now has 40 vacation hours.  
    SELECT VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 1:On session 1:

    -- Reissue the SELECT statement - this shows  
    -- the employee having 48 vacation hours.  The  
    -- snapshot transaction is still reading data from  
    -- the versioned row.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 2:On session 2:

-- Commit the transaction; this commits the data  
-- modification.  
COMMIT TRANSACTION;  
GO  

Für Sitzung 1:On session 1:

    -- Reissue the SELECT statement - this still   
    -- shows the employee having 48 vacation hours  
    -- even after the other transaction has committed  
    -- the data modification.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  
  
    -- Because the data has been modified outside of the  
    -- snapshot transaction, any further data changes to   
    -- that data by the snapshot transaction will cause   
    -- the snapshot transaction to fail. This statement   
    -- will generate a 3960 error and the transaction will   
    -- terminate.  
    UPDATE HumanResources.Employee  
        SET SickLeaveHours = SickLeaveHours - 8  
        WHERE BusinessEntityID = 4;  
  
-- Undo the changes to the database from session 1.   
-- This will not undo the change from session 2.  
ROLLBACK TRANSACTION  
GO  

B.B. Arbeiten mit READ COMMITTED unter Verwendung der ZeilenversionsverwaltungWorking with read-committed using row versioning

In diesem Beispiel wird eine Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss und die Zeilenversionsverwaltung verwendet wird, gleichzeitig mit einer anderen Transaktion ausgeführt.In this example, a read-committed transaction using row versioning runs concurrently with another transaction. Die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, verhält sich anders als eine Momentaufnahmetransaktion.The read-committed transaction behaves differently than a snapshot transaction. Ebenso wie eine Momentaufnahmetransaktion liest die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, versionsspezifische Zeilen, nachdem die andere Transaktion Daten geändert hat.Like a snapshot transaction, the read-committed transaction will read versioned rows even after the other transaction has modified data. Im Gegensatz zu einer Momentaufnahmetransaktion gilt für die Transaktion, bei der ein Commit vor dem Lesevorgang ausgeführt werden muss, jedoch Folgendes:However, unlike a snapshot transaction, the read-committed transaction will:

  • Sie liest die geänderten Daten, nachdem die andere Transaktion ein Commit der Datenänderungen vorgenommen hat.Read the modified data after the other transaction commits the data changes.
  • Sie ist in der Lage, die von der anderen Transaktion bearbeiteten Daten zu aktualisieren, was der Momentaufnahmetransaktion nicht möglich ist.Be able to update the data modified by the other transaction where the snapshot transaction could not.

Für Sitzung 1:On session 1:

USE AdventureWorks2016;  -- Or any earlier version of the AdventureWorks database.  
GO  
  
-- Enable READ_COMMITTED_SNAPSHOT on the database.  
-- For this statement to succeed, this session  
-- must be the only connection to the AdventureWorks2016  
-- database.  
ALTER DATABASE AdventureWorks2016  
    SET READ_COMMITTED_SNAPSHOT ON;  
GO  
  
-- Start a read-committed transaction  
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;  
GO  
  
BEGIN TRANSACTION;  
    -- This SELECT statement will return  
    -- 48 vacation hours for the employee.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 2:On session 2:

USE AdventureWorks2016;  
GO  
  
-- Start a transaction.  
BEGIN TRANSACTION;  
    -- Subtract a vacation day from employee 4.  
    -- Update is not blocked by session 1 since  
    -- under read-committed using row versioning shared locks are  
    -- not requested.  
    UPDATE HumanResources.Employee  
        SET VacationHours = VacationHours - 8  
        WHERE BusinessEntityID = 4;  
  
    -- Verify that the employee now has 40 vacation hours.  
    SELECT VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 1:On session 1:

    -- Reissue the SELECT statement - this still shows  
    -- the employee having 48 vacation hours.  The  
    -- read-committed transaction is still reading data   
    -- from the versioned row and the other transaction   
    -- has not committed the data changes yet.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  

Für Sitzung 2:On session 2:

-- Commit the transaction.  
COMMIT TRANSACTION;  
GO  

Für Sitzung 1:On session 1:

    -- Reissue the SELECT statement which now shows the   
    -- employee having 40 vacation hours.  Being   
    -- read-committed, this transaction is reading the   
    -- committed data. This is different from snapshot  
    -- isolation which reads from the versioned row.  
    SELECT BusinessEntityID, VacationHours  
        FROM HumanResources.Employee  
        WHERE BusinessEntityID = 4;  
  
    -- This statement, which caused the snapshot transaction   
    -- to fail, will succeed with read-committed using row versioning.  
    UPDATE HumanResources.Employee  
        SET SickLeaveHours = SickLeaveHours - 8  
        WHERE BusinessEntityID = 4;  
  
-- Undo the changes to the database from session 1.   
-- This will not undo the change from session 2.  
ROLLBACK TRANSACTION;  
GO  

Aktivieren von auf der Zeilenversionsverwaltung basierenden IsolationsstufenEnabling Row Versioning-Based Isolation Levels

Datenbankadministratoren steuern die Einstellungen für die Zeilenversionsverwaltung auf Datenbankebene über die Datenbankoptionen READ_COMMITTED_SNAPSHOT und ALLOW_SNAPSHOT_ISOLATION in der ALTER DATABASE-Anweisung.Database administrators control the database-level settings for row versioning by using the READ_COMMITTED_SNAPSHOT and ALLOW_SNAPSHOT_ISOLATION database options in the ALTER DATABASE statement.

Wenn die READ_COMMITTED_SNAPSHOT-Datenbankoption auf ON festgelegt ist, werden die zur Unterstützung der Option verwendeten Mechanismen unmittelbar aktiviert.When the READ_COMMITTED_SNAPSHOT database option is set ON, the mechanisms used to support the option are activated immediately. Wenn die READ_COMMITTED_SNAPSHOT-Option festgelegt wird, wird in der Datenbank nur die Verbindung zugelassen, die den ALTER DATABASE-Befehl ausführt.When setting the READ_COMMITTED_SNAPSHOT option, only the connection executing the ALTER DATABASE command is allowed in the database. So lange ALTER DATABASE nicht abgeschlossen ist, darf keine andere offene Verbindung in der Datenbank bestehen.There must be no other open connection in the database until ALTER DATABASE is complete. Die Datenbank muss sich nicht im Einzelbenutzermodus befinden.The database does not have to be in single-user mode.

Die folgende Transact-SQLTransact-SQL-Anweisung aktiviert READ_COMMITTED_SNAPSHOT:The following Transact-SQLTransact-SQL statement enables READ_COMMITTED_SNAPSHOT:

ALTER DATABASE AdventureWorks2016  
    SET READ_COMMITTED_SNAPSHOT ON;  

Wenn für die ALLOW_SNAPSHOT_ISOLATION-Datenbankoption der Wert ON festgelegt ist, generiert die SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz so lange keine Zeilenversionen für geänderte Daten, bis alle aktiven Transaktionen abgeschlossen sind, durch die Daten in der Datenbank geändert werden.When the ALLOW_SNAPSHOT_ISOLATION database option is set ON, the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine does not generate row versions for modified data until all active transactions that have modified data in the database complete. Wenn aktive Änderungstransaktionen vorhanden sind, legt SQL ServerSQL Server den Status der Option auf PENDING_ON fest.If there are active modification transactions, SQL ServerSQL Server sets the state of the option to PENDING_ON. Wenn alle Änderungstransaktionen abgeschlossen sind, wird der Status der Option zu ON geändert.After all of the modification transactions complete, the state of the option is changed to ON. Die Benutzer können keine Momentaufnahmetransaktion in dieser Datenbank starten, bis die Option vollständig ON ist.Users cannot start a snapshot transaction in that database until the option is fully ON. Die Datenbank übergibt einen PENDING_OFF-Status, wenn der Datenbankadministrator die ALLOW_SNAPSHOT_ISOLATION-Option auf OFF festlegt.The database passes through a PENDING_OFF state when the database administrator sets the ALLOW_SNAPSHOT_ISOLATION option to OFF.

Die folgende Transact-SQLTransact-SQL-Anweisung aktiviert ALLOW_SNAPSHOT_ISOLATION:The following Transact-SQLTransact-SQL statement will enable ALLOW_SNAPSHOT_ISOLATION:

ALTER DATABASE AdventureWorks2016  
    SET ALLOW_SNAPSHOT_ISOLATION ON;  

In der folgenden Tabelle werden die Statusmöglichkeiten der ALLOW_SNAPSHOT_ISOLATION-Option aufgeführt und beschrieben.The following table lists and describes the states of the ALLOW_SNAPSHOT_ISOLATION option. Der Zugriff von Benutzern auf Daten in der Datenbank wird durch das Verwenden von ALTER DATABASE mit der ALLOW_SNAPSHOT_ISOLATION-Option nicht blockiert.Using ALTER DATABASE with the ALLOW_SNAPSHOT_ISOLATION option does not block users who are currently accessing the database data.

Status der Momentaufnahmeisolationsumgebung der aktuellen DatenbankState of snapshot isolation framework for current database BESCHREIBUNGDescription
OFFOFF Die Unterstützung von Momentaufnahmeisolationstransaktionen ist nicht aktiviert.The support for snapshot isolation transactions is not activated. Momentaufnahmeisolationtransaktionen sind nicht zulässig.No snapshot isolation transactions are allowed.
PENDING_ONPENDING_ON Die Unterstützung von Momentaufnahmeisolationstransaktionen befindet sich in einem Übergangsstatus (von OFF nach ON).The support for snapshot isolation transactions is in transition state (from OFF to ON). Offene Transaktionen müssen abgeschlossen werden.Open transactions must complete.

Momentaufnahmeisolationtransaktionen sind nicht zulässig.No snapshot isolation transactions are allowed.
EINON Die Unterstützung von Momentaufnahmeisolationstransaktionen ist aktiviert.The support for snapshot isolation transactions is activated.

Momentaufnahmeisolationtransaktionen sind zulässig.Snapshot transactions are allowed.
PENDING_OFFPENDING_OFF Die Unterstützung von Momentaufnahmeisolationstransaktionen befindet sich in einem Übergangsstatus (von ON nach OFF).The support for snapshot isolation transactions is in transition state (from ON to OFF).

Momentaufnahmetransaktionen, die nach diesem Zeitpunkt gestartet werden, können nicht auf die Datenbank zugreifen.Snapshot transactions started after this time cannot access this database. Updatetransaktionen sind ist in dieser Datenbank noch durch die Versionsverwaltung eingeschränkt.Update transactions still pay the cost of versioning in this database. Vorhandene Momentaufnahmetransaktionen können immer noch problemlos auf die Datenbank zugreifen.Existing snapshot transactions can still access this database without a problem. Der PENDING_OFF-Status wird erst OFF, wenn alle Momentaufnahmetransaktionen abgeschlossen sind, die zu dem Zeitpunkt, als der Momentaufnahmeisolationsstatus der Datenbank ON war, aktiviert waren.The state PENDING_OFF does not become OFF until all snapshot transactions that were active when the database snapshot isolation state was ON finish.

Verwenden Sie die sys.databases-Katalogsicht, um den Status der beiden Datenbankoptionen zur Zeilenversionsverwaltung zu bestimmen.Use the sys.databases catalog view to determine the state of both row versioning database options.

Alle Updates von Benutzertabellen sowie bestimmte Updates von Systemtabellen, die in master und msdb gespeichert sind, generieren Zeilenversionen.All updates to user tables and some system tables stored in master and msdb generate row versions.

Die ALLOW_SNAPSHOT_ISOLATION-Option wird in den Datenbanken master und msdb automatisch auf ON festgelegt und kann nicht deaktiviert werden.The ALLOW_SNAPSHOT_ISOLATION option is automatically set ON in the master and msdb databases, and cannot be disabled.

Benutzer können die READ_COMMITTED_SNAPSHOT-Option in master, tempdb und msdb nicht auf ON festlegen.Users cannot set the READ_COMMITTED_SNAPSHOT option ON in master, tempdb, or msdb.

Verwenden von auf Zeilenversionsverwaltung basierenden IsolationsstufenUsing Row Versioning-based Isolation Levels

Das Framework für die Zeilenversionsverwaltung ist in SQL ServerSQL Server immer aktiviert und wird von mehreren Funktionen verwendet.The row versioning framework is always enabled in SQL ServerSQL Server, and is used by multiple features. Es stellt nicht nur auf Zeilenversionsverwaltung basierende Isolationsstufen bereit, sondern wird auch zur Unterstützung von Änderungen verwendet, die an Triggern und MARS-Sitzungen (Multiple Active Result Sets) vorgenommen werden; außerdem dient es zur Unterstützung von Datenlesevorgängen für ONLINE-Indexvorgänge.Besides providing row versioning-based isolation levels, it is used to support modifications made in triggers and multiple active result sets (MARS) sessions, and to support data reads for ONLINE index operations.

Auf der Zeilenversionsverwaltung basierende Isolationsstufen werden auf der Datenbankebene aktiviert.Row versioning-based isolation levels are enabled at the database level. Alle Anwendungen, die auf Objekte aus aktivierten Datenbanken zugreifen, können mithilfe der folgenden Isolationsstufen Abfragen ausführen:Any application accessing objects from enabled databases can run queries using the following isolation levels:

  • READ COMMITTED (Commit vor dem Lesevorgang) mit Zeilenversionsverwaltung, indem die READ_COMMITTED_SNAPSHOT-Datenbankoption auf ON (wie im folgenden Codebeispiel gezeigt) festgelegt wird:Read-committed that uses row versioning by setting the READ_COMMITTED_SNAPSHOT database option to ON as shown in the following code example:

    ALTER DATABASE AdventureWorks2016  
        SET READ_COMMITTED_SNAPSHOT ON;  
    

    Wenn die Datenbank für READ_COMMITTED_SNAPSHOT aktiviert ist, verwenden alle Abfragen, die unter der Isolationsstufe READ COMMITTED ausgeführt werden, Zeilenversionsverwaltung. Dies bedeutet, dass die Lesevorgänge die Updatevorgänge nicht blockieren.When the database is enabled for READ_COMMITTED_SNAPSHOT, all queries running under the read committed isolation level use row versioning, which means that read operations do not block update operations.

  • Die Momentaufnahmeisolation durch Festlegen der Datenbankoption ALLOW_SNAPSHOT_ISOLATION auf ON, wie im folgenden Codebeispiel gezeigt:Snapshot isolation by setting the ALLOW_SNAPSHOT_ISOLATION database option to ON as shown in the following code example:

    ALTER DATABASE AdventureWorks2016  
        SET ALLOW_SNAPSHOT_ISOLATION ON;  
    

    Eine Transaktion, die unter Momentaufnahmeisolation ausgeführt wird, kann auf Tabellen in der Datenbank zugreifen, die für die Snapshotfunktion aktiviert wurden.A transaction running under snapshot isolation can access tables in the database that have been enabled for snapshot. Wenn auf Tabellen zugegriffen werden soll, die nicht für Momentaufnahmen aktiviert wurden, muss die Isolationsstufe geändert werden.To access tables that have not been enabled for snapshot, the isolation level must be changed. Das folgende Codebeispiel zeigt z. B. eine SELECT-Anweisung, die während der Ausführung unter einer Momentaufnahmetransaktion zwei Tabellen verknüpft.For example, the following code example shows a SELECT statement that joins two tables while running under a snapshot transaction. Eine der Tabellen gehört zu einer Datenbank, in der Momentaufnahmeisolation nicht aktiviert ist.One table belongs to a database in which snapshot isolation is not enabled. Wenn die SELECT-Anweisung unter Momentaufnahmeisolation ausgeführt wird, ist die Ausführung nicht erfolgreich.When the SELECT statement runs under snapshot isolation, it fails to execute successfully.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;  
    BEGIN TRAN  
        SELECT t1.col5, t2.col5  
            FROM Table1 as t1  
            INNER JOIN SecondDB.dbo.Table2 as t2  
                ON t1.col1 = t2.col2;  
    

    Das folgende Codebeispiel zeigt die gleiche SELECT-Anweisung, die so bearbeitet wurde, dass die Transaktionsisolationsstufe in READ COMMITTED geändert wurde.The following code example shows the same SELECT statement that has been modified to change the transaction isolation level to read-committed. Durch diese Änderung wird die SELECT-Anweisung erfolgreich ausgeführt.Because of this change, the SELECT statement executes successfully.

    SET TRANSACTION ISOLATION LEVEL SNAPSHOT;  
    BEGIN TRAN  
        SELECT t1.col5, t2.col5  
            FROM Table1 as t1  
            WITH (READCOMMITTED)  
            INNER JOIN SecondDB.dbo.Table2 as t2  
                ON t1.col1 = t2.col2;  
    

Einschränkungen von Transaktionen, die auf Zeilenversionsverwaltung basierende Isolationsstufen verwendenLimitations of Transactions Using Row Versioning-based Isolation Levels

Berücksichtigen Sie die folgenden Einschränkungen, wenn Sie mit auf Zeilenversionsverwaltung basierenden Isolationsstufen arbeiten:Consider the following limitations when working with row versioning-based isolation levels:

  • READ_COMMITTED_SNAPSHOT kann in tempdb, msdb oder master nicht aktiviert werden.READ_COMMITTED_SNAPSHOT cannot be enabled in tempdb, msdb, or master.

  • Globale temporäre Tabellen werden in tempdb gespeichert.Global temp tables are stored in tempdb. Wenn auf globale temporäre Tabellen in einer Momentaufnahmetransaktion zugegriffen wird, muss einer der folgenden Vorgänge erfolgen:When accessing global temp tables inside a snapshot transaction, one of the following must happen:

    • Festlegen der ALLOW_SNAPSHOT_ISOLATION-Datenbankoption auf ON in tempdb.Set the ALLOW_SNAPSHOT_ISOLATION database option ON in tempdb.
    • Verwenden eines Isolationshinweises zum Ändern der Isolationsstufe für die Anweisung.Use an isolation hint to change the isolation level for the statement.
  • Momentaufnahmetransaktionen erzeugen einen Fehler, wenn Folgendes zutrifft:Snapshot transactions fail when:

    • Eine Datenbank erhält nach dem Start der Momentaufnahmetransaktion, jedoch vor dem Zugriff auf die Datenbank durch die Momentaufnahmetransaktion einen Schreibschutz.A database is made read-only after the snapshot transaction starts, but before the snapshot transaction accesses the database.
    • Beim Zugriff auf Objekte aus mehreren Datenbanken wurde ein Datenbankstatus so geändert, dass die Datenbankwiederherstellung nach dem Start einer Momentaufnahmetransaktion aufgetreten ist, jedoch vor dem Zugriff auf die Datenbank durch die Momentaufnahmetransaktion.If accessing objects from multiple databases, a database state was changed in such a way that database recovery occurred after a snapshot transaction starts, but before the snapshot transaction accesses the database. Beispiel: Die Datenbank wurde auf OFFLINE und dann auf ONLINE festgelegt, auf automatisches Schließen und Öffnen oder auf Trennen und Anfügen.For example: the database was set to OFFLINE and then to ONLINE, database autoclose and open, or database detach and attach.
  • Verteilte Transaktionen, z. B. Abfragen in verteilten partitionierten Datenbanken, werden unter Momentaufnahmeisolation nicht unterstützt.Distributed transactions, including queries in distributed partitioned databases, are not supported under snapshot isolation.

  • SQL ServerSQL Server speichert nicht mehrere Versionen von Systemmetadaten.does not keep multiple versions of system metadata. DDL-Anweisungen (Data Definition Language) für Tabellen und andere Datenbankobjekte (Indizes, Sichten, Datentypen, gespeicherte Prozeduren und CLR-Funktionen) verändern Metadaten.Data definition language (DDL) statements on tables and other database objects (indexes, views, data types, stored procedures, and common language runtime functions) change metadata. Wenn eine DDL-Anweisung ein Objekt ändert, bewirkt jeder gleichzeitige Verweis auf das Objekt unter Momentaufnahmeisolation, dass die Momentaufnahmetransaktion einen Fehler erzeugt.If a DDL statement modifies an object, any concurrent reference to the object under snapshot isolation causes the snapshot transaction to fail. Für READ COMMITTED-Transaktionen gilt diese Einschränkung nicht, wenn die READ_COMMITTED_SNAPSHOT-Datenbankoption auf ON festgelegt wurde.Read-committed transactions do not have this limitation when the READ_COMMITTED_SNAPSHOT database option is ON.

    Ein Datenbankadministrator führt z. B. die folgende ALTER INDEX-Anweisung aus.For example, a database administrator executes the following ALTER INDEX statement.

    USE AdventureWorks2016;  
    GO  
    ALTER INDEX AK_Employee_LoginID  
        ON HumanResources.Employee REBUILD;  
    GO  
    

    Für alle Momentaufnahmetransaktionen, die während der Ausführung der ALTER INDEX-Anweisung aktiviert sind, wird ein Fehler ausgegeben, wenn versucht wird, auf die HumanResources.Employee-Tabelle zu verweisen, nachdem die ALTER INDEX-Anweisung ausgeführt wurde.Any snapshot transaction that is active when the ALTER INDEX statement is executed receives an error if it attempts to reference the HumanResources.Employee table after the ALTER INDEX statement is executed. READ COMMITTED-Transaktionen, die Zeilenversionsverwaltung verwenden, sind nicht betroffen.Read-committed transactions using row versioning are not affected.

    Hinweis

    BULK INSERT-Operationen können Änderungen an den Metadaten der Zieltabelle verursachen (z. B. beim Deaktivieren von Einschränkungsprüfungen).BULK INSERT operations may cause changes to target table metadata (for example, when disabling constraint checks). Sollte dies der Fall sein, schlagen gleichzeitige Momentaufnahmeisolationstransaktion fehl, die auf Tabellen mit BULK INSERT zugreifen.When this happens, concurrent snapshot isolation transactions accessing bulk inserted tables fail.

Anpassen von Sperren und ZeilenversionsverwaltungCustomizing Locking and Row Versioning

Anpassen des Timeouts für SperrenCustomizing the Lock Time-Out

Wenn eine MicrosoftMicrosoft SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz einer Transaktion keine Sperre für eine Ressource erteilen kann, da eine andere Transaktion bereits eine widersprüchliche Sperre für diese Ressource besitzt, wird die erste Transaktion blockiert, während sie darauf wartet, dass die vorhandene Sperre aufgehoben wird.When an instance of the MicrosoftMicrosoft SQL Server-Datenbank-EngineSQL Server Database Engine cannot grant a lock to a transaction because another transaction already owns a conflicting lock on the resource, the first transaction becomes blocked waiting for the existing lock to be released. Standardmäßig gibt es keinen obligatorischen Timeoutzeitraum und keine Möglichkeit, im Voraus zu testen, ob eine Ressource gesperrt ist, außer zu versuchen, auf die Daten zuzugreifen (und eventuell auf unbestimmte Zeit blockiert zu werden).By default, there is no mandatory time-out period and no way to test whether a resource is locked before locking it, except to attempt to access the data (and potentially get blocked indefinitely).

Hinweis

Verwenden Sie die dynamische Verwaltungssicht sys.dm_os_waiting_tasks in SQL ServerSQL Server, um zu bestimmen, ob und wodurch ein Prozess blockiert wird.In SQL ServerSQL Server, use the sys.dm_os_waiting_tasks dynamic management view to determine whether a process is being blocked and who is blocking it. Verwenden Sie die gespeicherte Systemprozedur sp_who in früheren Versionen von SQL ServerSQL Server.In earlier versions of SQL ServerSQL Server, use the sp_who system stored procedure.

Mithilfe der LOCK_TIMEOUT-Einstellung kann eine Anwendung eine Zeitspanne festlegen, die angibt, wie lange eine Anweisung maximal auf eine blockierte Ressource wartet.The LOCK_TIMEOUT setting allows an application to set a maximum time that a statement waits on a blocked resource. Wenn eine Anweisung länger wartet als in der LOCK_TIMEOUT-Einstellung angegeben, wird die blockierte Anweisung automatisch abgebrochen und die Fehlermeldung 1222 (Lock request time-out period exceeded) an die Anwendung zurückgegeben.When a statement has waited longer than the LOCK_TIMEOUT setting, the blocked statement is canceled automatically, and error message 1222 (Lock request time-out period exceeded) is returned to the application. Für eine Transaktion, in der diese Anweisung enthalten ist, wird jedoch von SQL ServerSQL Server kein Rollback ausgeführt, und sie wird nicht abgebrochen.Any transaction containing the statement, however, is not rolled back or canceled by SQL ServerSQL Server. Die Anwendung muss daher über einen Fehlerhandler verfügen, der die Fehlermeldung 1222 identifizieren kann.Therefore, the application must have an error handler that can trap error message 1222. Ist dies nicht der Fall, kann die Anwendung fortfahren, ohne zu erkennen, dass eine einzelne Anweisung in einer Transaktion abgebrochen wurde, und Fehler können auftreten, da nachfolgende Anweisungen in der Transaktion möglicherweise von der nicht ausgeführten Anweisung abhängen.If an application does not trap the error, the application can proceed unaware that an individual statement within a transaction has been canceled, and errors can occur because statements later in the transaction might depend on the statement that was never executed.

Durch das Implementieren eines Fehlerhandlers, der die Fehlermeldung 1222 auffängt, kann eine Anwendung die Timeoutbedingung bearbeiten und Abhilfemaßnahmen ergreifen, wie etwa die vormals blockierte Anforderung automatisch erneut zu senden oder für die gesamte Transaktion einen Rollback auszuführen.Implementing an error handler that traps error message 1222 allows an application to handle the time-out situation and take remedial action, such as: automatically resubmitting the statement that was blocked or rolling back the entire transaction.

Führen Sie die @@LOCK_TIMEOUT-Funktion aus, um die aktuelle LOCK_TIMEOUT-Einstellung zu bestimmen:To determine the current LOCK_TIMEOUT setting, execute the @@LOCK_TIMEOUT function:

SELECT @@lock_timeout;  
GO  

Anpassen der Isolationsstufe von TransaktionenCustomizing Transaction Isolation Level

READ COMMITTED ist die Standardisolationsstufe für MicrosoftMicrosoft SQL Server-Datenbank-EngineSQL Server Database Engine.READ COMMITTED is the default isolation level for the MicrosoftMicrosoft SQL Server-Datenbank-EngineSQL Server Database Engine. Wenn für eine bestimmte Anwendung eine andere Isolationsstufe erforderlich ist, kann eine der folgenden Methoden verwendet werden, um die entsprechende Isolationsstufe anzugeben:If an application must operate at a different isolation level, it can use the following methods to set the isolation level:

  • Ausführen der SET TRANSACTION ISOLATION LEVEL-Anweisung.Run the SET TRANSACTION ISOLATION LEVEL statement.
  • In ADO.NET-Anwendungen, von denen der verwaltete Namespace System.Data.SqlClient verwendet wird, kann mithilfe der SqlConnection.BeginTransaction-Methode die Option IsolationLevel angeben werden.ADO.NET applications that use the System.Data.SqlClient managed namespace can specify an IsolationLevel option by using the SqlConnection.BeginTransaction method.
  • Anwendungen, die ADO verwenden, können die Autocommit Isolation Levels-Eigenschaft festlegen.Applications that use ADO can set the Autocommit Isolation Levels property.
  • Beim Starten einer Transaktion können Anwendungen, für die OLE DB verwendet wird, „ITransactionLocal::StartTransaction“ aufrufen, wobei isoLevel auf die gewünschte Transaktionsisolationsstufe festgelegt wird.When starting a transaction, applications using OLE DB can call ITransactionLocal::StartTransaction with isoLevel set to the desired transaction isolation level. Beim Angeben der Isolationsstufe im Autocommitmodus können Anwendungen, von denen OLE DB verwendet wird, die DBPROPSET_SESSION-Eigenschaft DBPROP_SESS_AUTOCOMMITISOLEVELS auf die gewünschte Transaktionsisolationsstufe festlegen.When specifying the isolation level in autocommit mode, applications that use OLE DB can set the DBPROPSET_SESSION property DBPROP_SESS_AUTOCOMMITISOLEVELS to the desired transaction isolation level.
  • In Anwendungen, für die ODBC verwendet wird, kann mithilfe von „SQLSetConnectAttr“ das SQL_COPT_SS_TXN_ISOLATION-Attribut festlegt werden.Applications that use ODBC can set the SQL_COPT_SS_TXN_ISOLATION attribute by using SQLSetConnectAttr.

Wenn eine Isolationsstufe angegeben ist, richtet sich das Sperrverhalten aller Abfragen und DML-Anweisungen (Data Manipulation Language, Datenbearbeitungssprache) der SQL ServerSQL Server-Sitzung nach dieser Isolationsstufe.When the isolation level is specified, the locking behavior for all queries and data manipulation language (DML) statements in the SQL ServerSQL Server session operates at that isolation level. Die Isolationsstufe bleibt gültig, bis die Sitzung beendet wird oder bis eine andere Isolationsstufe festgelegt wird.The isolation level remains in effect until the session terminates or until the isolation level is set to another level.

Im folgenden Beispiel wird die SERIALIZABLE-Isolationsstufe festgelegt:The following example sets the SERIALIZABLE isolation level:

USE AdventureWorks2016;  
GO  
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;  
GO  
BEGIN TRANSACTION;  
SELECT BusinessEntityID  
    FROM HumanResources.Employee;  
GO  

Die Isolationsstufe kann, falls notwendig, für einzelne Abfrage- oder DML-Anweisungen überschrieben werden, indem ein Hinweis auf Tabellenebene angegeben wird.The isolation level can be overridden for individual query or DML statements, if necessary, by specifying a table-level hint. Das Angeben eines Hinweises auf Tabellenebene wirkt sich nicht auf andere Anweisungen in der Sitzung aus.Specifying a table-level hint does not affect other statements in the session. Es wird empfohlen, dass Hinweise auf Tabellenebene zum Ändern des Standardverhaltens nur dann verwendet werden, wenn dies absolut notwendig ist.We recommend that table-level hints be used to change the default behavior only when absolutely necessary.

SQL Server-Datenbank-EngineSQL Server Database Engine muss möglicherweise beim Lesen von Metadaten selbst dann Sperren einrichten, wenn die Isolationsstufe auf eine Stufe festgelegt ist, für die zum Lesen von Daten keine freigegebenen Sperren erforderlich sind.The SQL Server-Datenbank-EngineSQL Server Database Engine might have to acquire locks when reading metadata even when the isolation level is set to a level where share locks are not requested when reading data. Eine in der READ UNCOMMITTED-Isolationsstufe ausgeführte Transaktion richtet beim Lesen von Daten beispielsweise keine freigegebenen Sperren ein, kann jedoch zu einem gewissen Zeitpunkt Sperren anfordern, wenn eine Systemkatalogsicht gelesen wird.For example, a transaction running at the read-uncommitted isolation level does not acquire share locks when reading data, but might sometime request locks when reading a system catalog view. Dies bedeutet, dass eine READ UNCOMMITTED-Transaktion beim Abfragen einer Tabelle Blockierungen verursachen kann, wenn eine andere Transaktion gleichzeitig die Metadaten der Tabelle ändert.This means it is possible for a read uncommitted transaction to cause blocking when querying a table when a concurrent transaction is modifying the metadata of that table.

Wenn Sie die derzeit für die Transaktion festgelegte Isolationsstufe ermitteln möchten, verwenden Sie die DBCC USEROPTIONS-Anweisung, wie im nachfolgenden Beispiel gezeigt.To determine the transaction isolation level currently set, use the DBCC USEROPTIONS statement as shown in the following example. Das hier aufgeführte Resultset weicht möglicherweise von dem auf Ihrem System angezeigten Resultset ab.The result set may vary from the result set on your system.

USE AdventureWorks2016;  
GO  
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;  
GO  
DBCC USEROPTIONS;  
GO  

Hier ist das Resultset.Here is the result set.

Set Option                   Value  
---------------------------- -------------------------------------------  
textsize                     2147483647  
language                     us_english  
dateformat                   mdy  
datefirst                    7  
...                          ...  
Isolation level              repeatable read  
 
(14 row(s) affected)   
 
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

SperrhinweiseLocking Hints

Sperrhinweise können für einzelne Tabellenverweise in den SELECT-, INSERT-, UPDATE- und DELETE-Anweisungen angegeben werden.Locking hints can be specified for individual table references in the SELECT, INSERT, UPDATE, and DELETE statements. Diese Hinweise geben den Typ der Sperre oder die Zeilenversionsverwaltung an, die die SQL Server-Datenbank-EngineSQL Server Database Engine-Instanz für die Tabellendaten verwendet.The hints specify the type of locking or row versioning the instance of the SQL Server-Datenbank-EngineSQL Server Database Engine uses for the table data. Sperrhinweise auf Tabellenebene können verwendet werden, wenn eine präzisere Steuerung der Sperrentypen für ein Objekt notwendig wird.Table-level locking hints can be used when a finer control of the types of locks acquired on an object is required. Diese Sperrhinweise überschreiben die aktuelle Transaktionsisolationsstufe für diese Sitzung.These locking hints override the current transaction isolation level for the session.

Weitere Informationen zu bestimmten Sperrhinweisen und ihrem Verhalten finden Sie unter Tabellenhinweise (Transact-SQL).For more information about the specific locking hints and their behaviors, see Table Hints (Transact-SQL).

Hinweis

Der SQL Server-Datenbank-EngineSQL Server Database Engine-Abfrageoptimierer wählt so gut wie immer die richtige Sperrebene aus.The SQL Server-Datenbank-EngineSQL Server Database Engine query optimizer almost always chooses the correct locking level. Es wird empfohlen, dass Sperrhinweise auf Tabellenebene zur Änderung des Standardsperrverhaltens nur dann verwendet werden, wenn dies notwendig ist.We recommend that table-level locking hints be used to change the default locking behavior only when necessary. Wenn eine Sperrstufe nicht zugelassen wird, kann dies negative Auswirkungen auf die Parallelität haben.Disallowing a locking level can adversely affect concurrency.

SQL Server-Datenbank-EngineSQL Server Database Engine muss möglicherweise beim Lesen von Metadaten selbst dann Sperren aktivieren, wenn eine SELECT-Anweisung mit einem Sperrhinweis verarbeitet wird, der beim Lesen von Daten Anforderungen für freigegebene Sperren verhindert.The SQL Server-Datenbank-EngineSQL Server Database Engine might have to acquire locks when reading metadata, even when processing a select with a locking hint that prevents requests for share locks when reading data. Eine SELECT-Anweisung, die den NOLOCK-Hinweis verwendet, aktiviert beim Lesen von Daten z.B. keine freigegebenen Sperren, kann jedoch manchmal Sperren anfordern, wenn eine Systemkatalogsicht gelesen wird.For example, a SELECT using the NOLOCK hint does not acquire share locks when reading data, but might sometime request locks when reading a system catalog view. Dies bedeutet, dass es möglich ist, eine SELECT-Anweisung zu blockieren, die NOLOCK verwendet.This means it is possible for a SELECT statement using NOLOCK to be blocked.

Wenn – wie im folgenden Beispiel gezeigt – die Isolationsstufe für Transaktionen als SERIALIZABLE festgelegt wurde und der NOLOCK-Sperrhinweis auf Tabellenebene mit der SELECT-Anweisung verwendet wird, werden keine Schlüsselbereichssperren angewendet, die in der Regel zur Aufrechterhaltung der Serialisierbarkeit von Transaktionen verwendet werden.As shown in the following example, if the transaction isolation level is set to SERIALIZABLE, and the table-level locking hint NOLOCK is used with the SELECT statement, key-range locks typically used to maintain serializable transactions are not taken.

USE AdventureWorks2016;  
GO  
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;  
GO  
BEGIN TRANSACTION;  
GO  
SELECT JobTitle  
    FROM HumanResources.Employee WITH (NOLOCK);  
GO  
  
-- Get information about the locks held by   
-- the transaction.  
SELECT    
        resource_type,   
        resource_subtype,   
        request_mode  
    FROM sys.dm_tran_locks  
    WHERE request_session_id = @@spid;  
  
-- End the transaction.  
ROLLBACK;  
GO  

Die einzige Sperre, die angewendet wird und auf HumanResources.Employee verweist, ist eine Sperre des Typs Sch-S (Schemastabilität).The only lock taken that references HumanResources.Employee is a schema stability (Sch-S) lock. In diesem Fall kann die Serialisierbarkeit nicht mehr garantiert werden.In this case, serializability is no longer guaranteed.

In SQL Server 2019 (15.x)SQL Server 2019 (15.x) kann die LOCK_ESCALATION-Option von ALTER TABLE Tabellensperren als unerwünscht festlegen und HoBT-Sperren für partitionierte Tabellen aktivieren.In SQL Server 2019 (15.x)SQL Server 2019 (15.x), the LOCK_ESCALATION option of ALTER TABLE can disfavor table locks, and enable HoBT locks on partitioned tables. Diese Option ist kein Sperrhinweis, kann jedoch verwendet werden, um die Sperrenausweitung zu reduzieren.This option is not a locking hint, but can but used to reduce lock escalation. Weitere Informationen finden Sie unter ALTER TABLE (Transact-SQL).For more information, see ALTER TABLE (Transact-SQL).

Anpassen der Sperren für einen IndexCustomizing Locking for an Index

SQL Server-Datenbank-EngineSQL Server Database Engine verwendet eine dynamische Sperrstrategie, die für Abfragen in den meisten Fällen automatisch die am besten geeignete Granularität der Sperren auswählt.The SQL Server-Datenbank-EngineSQL Server Database Engine uses a dynamic locking strategy that automatically chooses the best locking granularity for queries in most cases. Es empfiehlt sich, die Standardeinstellungen der Sperrebenen, in denen die Seiten- und Zeilensperre aktiviert ist, nicht zu überschreiben, es sei denn, die Zugriffsmuster für Tabellen oder Indizes sind bekannt und konsistent und es liegt ein Ressourcenkonflikt vor, der behoben werden muss.We recommend that you do not override the default locking levels, which have page and row locking on, unless table or index access patterns are well understood and consistent, and there is a resource contention problem to solve. Das Überschreiben einer Sperrebene kann den gleichzeitigen Zugriff auf eine Tabelle oder einen Index signifikant einschränken.Overriding a locking level can significantly impede concurrent access to a table or index. Wenn beispielsweise in einer großen Tabelle, auf die viele Benutzer zugreifen, nur Sperren auf Tabellenebene angegeben werden, kann dies zu Engpässen führen, da die Benutzer die Aufhebung der Sperre auf Tabellenebene abwarten müssen, bevor sie auf die Tabelle zugreifen können.For example, specifying only table-level locks on a large table that users access heavily can cause bottlenecks because users must wait for the table-level lock to be released before accessing the table.

Wenn die Zugriffsmuster gut bekannt und konsistent sind, kann das Untersagen von Seiten- oder Zeilensperren in einigen Fällen sinnvoll sein.There are a few cases where disallowing page or row locking can be beneficial, if the access patterns are well understood and consistent. So verwendet beispielsweise eine Datenbankanwendung eine Nachschlagetabelle, die wöchentlich in einem Batchverarbeitungsprozess aktualisiert wird.For example, a database application uses a lookup table that is updated weekly in a batch process. Gleichzeitige Leser greifen mit einer freigegebenen Sperre (S) auf die Tabelle zu. Das wöchentliche Batchupdate greift mit einer exklusiven Sperre (X) auf die Tabelle zu.Concurrent readers access the table with a shared (S) lock and the weekly batch update accesses the table with an exclusive (X) lock. Durch das Deaktivieren der Seiten- und Zeilensperrung für die Tabelle wird der Sperraufwand unter der Woche reduziert, indem Leser mithilfe freigegebener Tabellensperren gleichzeitig auf die Tabelle zugreifen können.Turning off page and row locking on the table reduces the locking overhead throughout the week by allowing readers to concurrently access the table through shared table locks. Wenn der Batchauftrag ausgeführt wird, kann er das Update effizient ausführen, da er eine exklusive Tabellensperre erhält.When the batch job runs, it can complete the update efficiently because it obtains an exclusive table lock.

Die Deaktivierung der Seiten- und Zeilensperre kann, muss jedoch nicht akzeptiert werden, da das wöchentliche Batchupdate die gleichzeitigen Leser während des Updates daran hindert, auf die Tabelle zuzugreifen.Turning off page and row locking might or might not be acceptable because the weekly batch update will block the concurrent readers from accessing the table while the update runs. Wenn durch den Batchauftrag nur einige Zeilen oder Seiten geändert werden, können Sie die Sperrebene ändern, sodass Sperren auf Zeilen- oder Seitenebene zugelassen werden. Dadurch können andere Sitzungen aus der Tabelle lesen, ohne diese zu sperren.If the batch job only changes a few rows or pages, you can change the locking level to allow row or page level locking, which will enable other sessions to read from the table without blocking. Wenn der Batchauftrag sehr viele Updates enthält, ist es möglicherweise die beste Methode, eine exklusive Sperre für die Tabelle zu setzen, um sicherzustellen, dass der Auftrag effizient ausgeführt wird.If the batch job has a large number of updates, obtaining an exclusive lock on the table may be the best way to ensure the batch job finishes efficiently.

Gelegentlich kann es zu einem Deadlock kommen, wenn zwei gleichzeitig ausgeführte Vorgänge Sperren für die gleiche Tabelle abrufen und dann blockieren, da beide die Seite sperren müssen.Occasionally a deadlock occurs when two concurrent operations acquire row locks on the same table and then block because they both need to lock the page. Wenn keine Zeilensperren zugelassen werden, wird erzwungen, dass einer der Vorgänge wartet, um den Deadlock zu vermeiden.Disallowing row locks forces one of the operations to wait, avoiding the deadlock.

Die Granularität der Sperren für einen Index kann mithilfe der Anweisungen CREATE INDEX und ALTER INDEX festgelegt werden.The granularity of locking used on an index can be set using the CREATE INDEX and ALTER INDEX statements. Die Einstellungen für die Sperre werden sowohl auf die Indexseiten als auch auf die Tabellenseiten angewendet.The lock settings apply to both the index pages and the table pages. Darüber hinaus können die Anweisungen CREATE TABLE und ALTER TABLE dazu verwendet werden, die Granularität der Sperren für PRIMARY KEY- und UNIQUE-Einschränkungen festzulegen.In addition, the CREATE TABLE and ALTER TABLE statements can be used to set locking granularity on PRIMARY KEY and UNIQUE constraints. Aus Gründen der Abwärtskompatibilität kann auch die gespeicherte Systemprozedur sp_indexoption zum Festlegen der Granularität verwendet werden.For backwards compatibility, the sp_indexoption system stored procedure can also set the granularity. Verwenden Sie zum Anzeigen der aktuellen Sperroption für einen bestimmten Index die INDEXPROPERTY-Funktion.To display the current locking option for a given index, use the INDEXPROPERTY function. Es ist möglich, Sperren auf Seitenebene, auf Zeilenebene oder eine Kombination von Sperren auf Seiten- und Zeilenebene für einen bestimmten Index nicht zuzulassen.Page-level locks, row-level locks, or a combination of page-level and row-level locks can be disallowed for a given index.

Nicht zugelassene SperrenDisallowed locks Indexzugriff durchIndex accessed by
SeitenebenePage level Sperren auf Zeilen- und TabellenebeneRow-level and table-level locks
ZeilenebeneRow level Sperren auf Seiten- und TabellenebenePage-level and table-level locks
Seiten- und ZeilenebenePage level and row level Sperren auf TabellenebeneTable-level locks

Weiterführende Themen zu TransaktionenAdvanced Transaction Information

Schachteln von TransaktionenNesting Transactions

Explizite Transaktionen können geschachtelt werden.Explicit transactions can be nested. Auf diese Weise sollen in erster Linie Transaktionen in gespeicherten Prozeduren unterstützt werden, die sowohl von einem Prozess, der sich bereits in einer Transaktion befindet, als auch von Prozessen, die keine aktiven Transaktionen aufweisen, aufgerufen werden können.This is primarily intended to support transactions in stored procedures that can be called either from a process already in a transaction or from processes that have no active transaction.

Im folgenden Beispiel wird dargestellt, wie geschachtelte Transaktionen verwendet werden sollten.The following example shows the intended use of nested transactions. Die TransProc-Prozedur erzwingt eine Transaktion, unabhängig vom Transaktionsmodus des Prozesses, der die Prozedur ausführt.The procedure TransProc enforces its transaction regardless of the transaction mode of any process that executes it. Wird TransProc aufgerufen, wenn eine Transaktion aktiv ist, wird die geschachtelte Transaktion in TransProc überwiegend ignoriert, und für ihre INSERT-Anweisungen wird ein Commit oder Rollback ausgeführt, je nachdem, welche endgültige Aktion für die äußere Transaktion durchgeführt wurde.If TransProc is called when a transaction is active, the nested transaction in TransProc is largely ignored, and its INSERT statements are committed or rolled back based on the final action taken for the outer transaction. Wenn TransProc von einem Prozess ausgeführt wird, der keine ausstehende Transaktion aufweist, führt COMMIT TRANSACTION am Ende der Prozedur letztendlich einen Commit für die INSERT-Anweisungen aus.If TransProc is executed by a process that does not have an outstanding transaction, the COMMIT TRANSACTION at the end of the procedure effectively commits the INSERT statements.

SET QUOTED_IDENTIFIER OFF;  
GO  
SET NOCOUNT OFF;  
GO  
CREATE TABLE TestTrans(Cola INT PRIMARY KEY,  
               Colb CHAR(3) NOT NULL);  
GO  
CREATE PROCEDURE TransProc @PriKey INT, @CharCol CHAR(3) AS  
BEGIN TRANSACTION InProc  
INSERT INTO TestTrans VALUES (@PriKey, @CharCol)  
INSERT INTO TestTrans VALUES (@PriKey + 1, @CharCol)  
COMMIT TRANSACTION InProc;  
GO  
/* Start a transaction and execute TransProc. */  
BEGIN TRANSACTION OutOfProc;  
GO  
EXEC TransProc 1, 'aaa';  
GO  
/* Roll back the outer transaction, this will  
   roll back TransProc's nested transaction. */  
ROLLBACK TRANSACTION OutOfProc;  
GO  
EXECUTE TransProc 3,'bbb';  
GO  
/* The following SELECT statement shows only rows 3 and 4 are   
   still in the table. This indicates that the commit  
   of the inner transaction from the first EXECUTE statement of  
   TransProc was overridden by the subsequent rollback. */  
SELECT * FROM TestTrans;  
GO  

SQL Server-Datenbank-EngineSQL Server Database Engine ignoriert das Ausführen von Commits für innere Transaktionen.Committing inner transactions is ignored by the SQL Server-Datenbank-EngineSQL Server Database Engine. Für die Transaktion wird entweder ein Commit oder Rollback ausgeführt, je nachdem, welche Aktion am Ende der äußersten Transaktion durchgeführt wird.The transaction is either committed or rolled back based on the action taken at the end of the outermost transaction. Bei der Ausführung eines Commits für die äußere Transaktion wird für die inneren geschachtelten Transaktionen ebenfalls ein Commit ausgeführt.If the outer transaction is committed, the inner nested transactions are also committed. Bei der Ausführung eines Rollbacks für die äußere Transaktion wird auch für alle inneren Transaktionen ein Rollback ausgeführt, unabhängig davon, ob für jede einzelne der inneren Transaktionen ein Commit ausgeführt wurde oder nicht.If the outer transaction is rolled back, then all inner transactions are also rolled back, regardless of whether or not the inner transactions were individually committed.

Jeder Aufruf von COMMIT TRANSACTION oder COMMIT WORK gilt für die zuletzt ausgeführte BEGIN TRANSACTION.Each call to COMMIT TRANSACTION or COMMIT WORK applies to the last executed BEGIN TRANSACTION. Wenn die BEGIN TRANSACTION-Anweisungen geschachtelt sind, bezieht sich eine COMMIT-Anweisung nur auf die letzte geschachtelte Transaktion, also die innerste Transaktion.If the BEGIN TRANSACTION statements are nested, then a COMMIT statement applies only to the last nested transaction, which is the innermost transaction. Selbst wenn sich eine COMMIT TRANSACTION transaction_name-Anweisung in einer geschachtelten Transaktion auf den Transaktionsnamen der äußeren Transaktion bezieht, wird der Commit ausschließlich für die innerste Transaktion ausgeführt.Even if a COMMIT TRANSACTION transaction_name statement within a nested transaction refers to the transaction name of the outer transaction, the commit applies only to the innermost transaction.

Es ist nicht zulässig, dass der transaction_name-Parameter einer ROLLBACK TRANSACTION-Anweisung auf die inneren Transaktionen einer Reihe von benannten geschachtelten Transaktionen verweist.It is not legal for the transaction_name parameter of a ROLLBACK TRANSACTION statement to refer to the inner transactions of a set of named nested transactions. transaction_name kann nur auf den Transaktionsnamen der äußersten Transaktion verweisen.transaction_name can refer only to the transaction name of the outermost transaction. Wenn eine ROLLBACK TRANSACTION-transaction_name-Anweisung, die den Namen der äußeren Transaktion verwendet, auf einer beliebigen Ebene einer Reihe geschachtelter Transaktionen ausgeführt wird, wird für alle geschachtelten Transaktionen ein Rollback ausgeführt.If a ROLLBACK TRANSACTION transaction_name statement using the name of the outer transaction is executed at any level of a set of nested transactions, all of the nested transactions are rolled back. Wenn eine ROLLBACK WORK- oder ROLLBACK TRANSACTION-Anweisung ohne Angabe des transaction_name-Parameters auf einer beliebigen Ebene einer Reihe von geschachtelten Transaktionen ausgeführt wird, wird für alle geschachtelten Transaktionen, einschließlich der äußersten Transaktion, ein Rollback ausgeführt.If a ROLLBACK WORK or ROLLBACK TRANSACTION statement without a transaction_name parameter is executed at any level of a set of nested transaction, it rolls back all of the nested transactions, including the outermost transaction.

Die @@TRANCOUNT-Funktion zeichnet die aktuelle Schachtelungsebene der Transaktion auf.The @@TRANCOUNT function records the current transaction nesting level. Jede BEGIN TRANSACTION-Anweisung erhöht @@TRANCOUNT um den Wert 1.Each BEGIN TRANSACTION statement increments @@TRANCOUNT by one. Jede COMMIT TRANSACTION- oder COMMIT WORK-Anweisung verringert @@TRANCOUNT um den Wert 1.Each COMMIT TRANSACTION or COMMIT WORK statement decrements @@TRANCOUNT by one. Bei einer ROLLBACK WORK- oder ROLLBACK TRANSACTION-Anweisung ohne Transaktionsnamen wird für alle geschachtelten Transaktionen ein Rollback ausgeführt und @@TRANCOUNT auf 0 reduziert.A ROLLBACK WORK or a ROLLBACK TRANSACTION statement that does not have a transaction name rolls back all nested transactions and decrements @@TRANCOUNT to 0. Bei einer ROLLBACK TRANSACTION-Anweisung, die den Transaktionsnamen der äußersten Transaktion in einer Reihe geschachtelter Transaktionen verwendet, wird ein Rollback für alle geschachtelten Transaktionen ausgeführt und @@TRANCOUNT auf 0 reduziert.A ROLLBACK TRANSACTION that uses the transaction name of the outermost transaction in a set of nested transactions rolls back all of the nested transactions and decrements @@TRANCOUNT to 0. Wenn Sie nicht sicher sind, ob eine Transaktion bereits begonnen hat, können Sie mit SELECT @@TRANCOUNT ermitteln, ob der Wert 1 oder höher beträgt.When you are unsure if you are already in a transaction, SELECT @@TRANCOUNT to determine if it is 1 or more. Wenn @@TRANCOUNT gleich 0 ist, hat noch keine Transaktion begonnen.If @@TRANCOUNT is 0, you are not in a transaction.

Verwenden von gebundenen SitzungenUsing Bound Sessions

Gebundene Sitzungen vereinfachen die Koordination zwischen zahlreichen Aktionen, die auf demselben Server ausgeführt werden.Bound sessions ease the coordination of actions across multiple sessions on the same server. Sie ermöglichen, dass mehrere Sitzungen gemeinsam dieselben Transaktionen und Sperren nutzen und ohne Sperrkonflikte mit denselben Daten arbeiten können.Bound sessions allow two or more sessions to share the same transaction and locks, and can work on the same data without lock conflicts. Gebundene Sitzungen können aus mehreren Sitzungen in derselben Anwendung oder aus mehreren Anwendungen mit getrennten Sitzungen erstellt werden.Bound sessions can be created from multiple sessions within the same application or from multiple applications with separate sessions.

Soll eine Sitzung an einer gebundenen Sitzung beteiligt werden, muss sie sp_getbindtoken oder srv_getbindtoken (über Open Data Services) aufrufen, um ein Bindungstoken abzurufen.To participate in a bound session, a session calls sp_getbindtoken or srv_getbindtoken (through Open Data Services) to get a bind token. Ein Bindungstoken ist eine Zeichenfolge, die jede gebundene Transaktion eindeutig kennzeichnet.A bind token is a character string that uniquely identifies each bound transaction. Das Bindungstoken wird dann an die anderen Sitzungen gesendet, die an die aktuelle Sitzung gebunden werden sollen.The bind token is then sent to the other sessions to be bound with the current session. Die anderen Sitzungen werden durch Aufrufen von sp_bindsession mithilfe des Bindungstokens, das sie von der ersten Sitzung empfangen haben, an die Transaktion gebunden.The other sessions bind to the transaction by calling sp_bindsession, using the bind token received from the first session.

Hinweis

Eine Sitzung muss über eine aktive Benutzertransaktion verfügen, damit sp_getbindtoken oder srv_getbindtoken erfolgreich ausgeführt werden kann.A session must have an active user transaction in order for sp_getbindtoken or srv_getbindtoken to succeed.

Bindungstoken müssen durch den Anwendungscode, der die erste Sitzung herstellt, an den Anwendungscode gesendet werden, der eine nachfolgende Sitzung an die erste Sitzung bindet.Bind tokens must be transmitted from the application code that makes the first session to the application code that subsequently binds their sessions to the first session. Es gibt keine Transact-SQLTransact-SQL-Anweisung oder API-Funktion, die eine Anwendung verwenden kann, um das Bindungstoken für eine Transaktion abzurufen, die von einem anderen Prozess gestartet wurde.There is no Transact-SQLTransact-SQL statement or API function that an application can use to get the bind token for a transaction started by another process. Nachfolgend werden verschiedene Methoden zum Übertragen von Bindungstokens aufgeführt:Some of the methods that can be used to transmit a bind token include the following:

  • Wenn alle Sitzungen vom selben Anwendungsprozess initiiert werden, können die Bindungstoken im globalen Speicher gespeichert oder als Parameter an Funktionen übergeben werden.If the sessions are all initiated from the same application process, bind tokens can be stored in global memory or passed into functions as a parameter.

  • Wenn die Sitzungen jedoch von separaten Anwendungsprozessen initiiert werden, können die Bindungstoken mithilfe der prozessübergreifenden Kommunikation (IPC, Interprocess Communication), wie z. B. von Remoteprozeduraufrufen (RPCs, Remote Procedure Calls) oder DDE (Dynamic Data Exchange), übertragen werden.If the sessions are made from separate application processes, bind tokens can be transmitted using interprocess communication (IPC), such as a remote procedure call (RPC) or dynamic data exchange (DDE).

  • Bindungstoken können in einer Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine in einer Tabelle gespeichert werden, die von die Bindung zur ersten Sitzung herstellenden Prozessen gelesen werden kann.Bind tokens can be stored in a table in an instance of the SQL Server-Datenbank-EngineSQL Server Database Engine that can be read by processes wanting to bind to the first session.

Es kann jeweils nur eine Sitzung in einer Menge von gebundenen Sitzungen aktiv sein.Only one session in a set of bound sessions can be active at any time. Wenn eine Sitzung eine Anweisung auf der Instanz ausführt oder auf Ergebnisse von der Instanz wartet, können keine anderen gebundenen Sitzungen auf die Instanz zugreifen, bis die aktuelle Sitzung die aktuelle Anweisung vollständig verarbeitet hat oder abbricht.If one session is executing a statement on the instance or has results pending from the instance, no other session bound to it can access the instance until the current session finishes processing or cancels the current statement. Ist die Instanz mit der Verarbeitung einer Anweisung einer anderen gebundenen Sitzung ausgelastet, zeigt eine Fehlermeldung an, dass der Transaktionsbereich verwendet wird und der Zugriffsversuch der Sitzung später wiederholt werden kann.If the instance is busy processing a statement from another of the bound sessions, an error occurs indicating that the transaction space is in use and the session should retry later.

Beim Binden von Sitzungen behält jede Sitzung ihre eigene Isolationsstufeneinstellung bei.When you bind sessions, each session retains its isolation level setting. Das Verwenden von SET TRANSACTION ISOLATION LEVEL zum Ändern der Isolationsstufeneinstellung einer Sitzung wirkt sich nicht auf die Einstellung anderer gebundener Sitzungen aus.Using SET TRANSACTION ISOLATION LEVEL to change the isolation level setting of one session does not affect the setting of any other session bound to it.

Typen von gebundenen SitzungenTypes of Bound Sessions

Gebundene Sitzungen lassen sich in lokale und verteilte gebundene Sitzungen unterteilen.The two types of bound sessions are local and distributed.

  • Lokale gebundene SitzungenLocal bound session
    Ermöglichen, dass gebundene Sitzungen den Transaktionsbereich einer einzelnen Instanz von SQL Server-Datenbank-EngineSQL Server Database Engine gemeinsam nutzen.Allows bound sessions to share the transaction space of a single transaction in a single instance of the SQL Server-Datenbank-EngineSQL Server Database Engine.

  • Verteilte gebundene SitzungenDistributed bound session
    Ermöglichen, dass gebundene Sitzungen dieselbe Transaktion auf zwei oder mehreren Instanzen gemeinsam nutzen, bis für die gesamte Transaktion mithilfe von MicrosoftMicrosoft Distributed Transaction Coordinator (MS DTC) ein Commit oder Rollback ausgeführt wird.Allows bound sessions to share the same transaction across two or more instances until the entire transaction is either committed or rolled back by using MicrosoftMicrosoft Distributed Transaction Coordinator (MS DTC).

Verteilte gebundene Sitzungen werden nicht durch ein Bindungstoken in Form einer Zeichenfolge gekennzeichnet, sondern durch numerische IDs für verteilte Transaktionen.Distributed bound sessions are not identified by a character string bind token; they are identified by distributed transaction identification numbers. Wenn eine gebundene Sitzung an einer lokalen Transaktion beteiligt ist und mit SET REMOTE_PROC_TRANSACTIONS ON einen Remoteprozeduraufruf (RPC) auf einem Remoteserver ausführt, wird die lokale gebundene Transaktion automatisch von MS DTC zu einer verteilten gebundenen Transaktion heraufgestuft und eine MS DTC-Sitzung gestartet.If a bound session is involved in a local transaction and executes an RPC on a remote server with SET REMOTE_PROC_TRANSACTIONS ON, the local bound transaction is automatically promoted to a distributed bound transaction by MS DTC and an MS DTC session is started.

Verwendung von gebundenen SitzungenWhen to use Bound Sessions

In früheren Versionen von SQL ServerSQL Server wurden gebundene Sitzungen hauptsächlich zum Entwickeln erweiterter gespeicherter Prozeduren verwendet, die Transact-SQLTransact-SQL-Anweisungen für den Prozess ausführen mussten, der sie aufgerufen hat.In earlier versions of SQL ServerSQL Server, bound sessions were primarily used in developing extended stored procedures that must execute Transact-SQLTransact-SQL statements on behalf of the process that calls them. Wenn der aufrufende Prozess ein Bindungstoken als Parameter an die erweiterte gespeicherte Prozedur übergibt, ermöglicht dies der Prozedur, den Transaktionsbereich des aufrufenden Prozesses mitzunutzen. Dadurch wird die erweiterte gespeicherte Prozedur in den aufrufenden Prozess integriert.Having the calling process pass in a bind token as one parameter of the extended stored procedure allows the procedure to join the transaction space of the calling process, thereby integrating the extended stored procedure with the calling process.

Im SQL Server-Datenbank-EngineSQL Server Database Engine sind mithilfe von CLR geschriebene gespeicherte Prozeduren sicherer, skalierbarer und stabiler als erweiterte gespeicherte Prozeduren.In the SQL Server-Datenbank-EngineSQL Server Database Engine, stored procedures written using CLR are more secure, scalable, and stable than extended stored procedures. CLR-gespeicherte Prozeduren verwenden nicht sp_bindsession, sondern das SqlContext-Objekt, um sich dem Kontext der aufrufenden Sitzung anzuschließen.CLR-stored procedures use the SqlContext object to join the context of the calling session, not sp_bindsession.

Gebundene Sitzungen können zum Entwickeln von dreistufigen Anwendungen verwendet werden. Geschäftsabläufe werden hierbei in getrennte Programme integriert, die gemeinsam für eine einzelne Geschäftstransaktion zuständig sind.Bound sessions can be used to develop three-tier applications in which business logic is incorporated into separate programs that work cooperatively on a single business transaction. Diese Programme müssen hinsichtlich der Koordination ihres Zugriffs auf die Datenbank sehr sorgfältig codiert werden.These programs must be coded to carefully coordinate their access to a database. Da die beiden Sitzungen die Sperren gemeinsam nutzen, dürfen die beiden Programme dieselben Daten nicht gleichzeitig ändern.Because the two sessions share the same locks, the two programs must not try to modify the same data at the same time. Zu einem gegebenen Zeitpunkt darf jeweils nur eine Sitzung als Teil der Transaktion Änderungen vornehmen – ein paralleles Ausführen von Vorgängen ist ausgeschlossen.At any point in time, only one session can be doing work as part of the transaction; there can be no parallel execution. Die Transaktion kann nur an bestimmten, gut definierten Zwischenergebnispunkten zwischen Sitzungen wechseln, z. B. wenn alle DML-Anweisungen abgeschlossen und deren Ergebnisse abgerufen wurden.The transaction can only be switched between sessions at well-defined yield points, such as when all DML statements have completed and their results have been retrieved.

Codieren effizienter TransaktionenCoding efficient transactions

Transaktionen sollten so kurz wie möglich gehalten werden.It is important to keep transactions as short as possible. Wenn eine Transaktion gestartet wird, muss ein Datenbank-Managementsystem (Database Management System, DBMS) viele Ressourcen bis zum Ende der Transaktion bereitstellen, um die ACID-Eigenschaften der Transaktion zu schützen.When a transaction is started, a database management system (DBMS) must hold many resources until the end of the transaction to protect the atomicity, consistency, isolation, and durability (ACID) properties of the transaction. Wenn Daten verändert werden, müssen die zu ändernden Zeilen durch exklusive Sperren geschützt werden, die verhindern, dass andere Transaktionen die Zeilen lesen. Diese exklusiven Sperren müssen so lange aufrechterhalten werden, bis für die Transaktion ein Commit oder Rollback ausgeführt wird.If data is modified, the modified rows must be protected with exclusive locks that prevent any other transaction from reading the rows, and exclusive locks must be held until the transaction is committed or rolled back. Abhängig von den Einstellungen der Isolationsstufen von Transaktionen können SELECT-Anweisungen Sperren einrichten, die bis zum Ausführen eines Commits oder Rollbacks für die Transaktion aufrechterhalten werden müssen.Depending on transaction isolation level settings, SELECT statements may acquire locks that must be held until the transaction is committed or rolled back. Vor allem bei Systemen mit zahlreichen Benutzern müssen Transaktionen so kurz wie möglich gehalten werden, um die Wahrscheinlichkeit zu reduzieren, dass bei gleichzeitigen Verbindungen Sperrkonflikte für Ressourcen auftreten.Especially in systems with many users, transactions must be kept as short as possible to reduce locking contention for resources between concurrent connections. Lang andauernde, ineffiziente Transaktionen sind bei wenigen Benutzern möglicherweise nicht problematisch, in einem System mit Tausenden von Benutzern jedoch inakzeptabel.Long-running, inefficient transactions may not be a problem with small numbers of users, but they are intolerable in a system with thousands of users. Ab SQL Server 2014 (12.x)SQL Server 2014 (12.x)SQL ServerSQL Server werden verzögerte dauerhafte Transaktionen unterstützt.Beginning with SQL Server 2014 (12.x)SQL Server 2014 (12.x)SQL ServerSQL Server supports delayed durable transactions. Verzögerte dauerhafte Transaktionen gewährleisten keine Dauerhaftigkeit.Delayed durable transactions do not guarantee durability. Weitere Informationen finden Sie im Thema Transaktionsdauerhaftigkeit.See the topic Transaction Durability for more information.

Richtlinien für das CodierenCoding Guidelines

Im Folgenden sind Richtlinien für das Codieren von effizienten Transaktionen aufgeführt:These are guidelines for coding efficient transactions:

  • Verzichten Sie auf Benutzereingaben während einer Transaktion.Do not require input from users during a transaction.
    Sorgen Sie dafür, dass alle notwendigen Eingaben von den Benutzern vor Beginn der Transaktion vorgenommen werden.Get all required input from users before a transaction is started. Wenn zusätzliche Benutzereingaben während einer Transaktion notwendig sind, führen Sie für die aktuelle Transaktion einen Rollback aus, und starten Sie die Transaktion neu, nachdem die Benutzereingaben erfolgt sind.If additional user input is required during a transaction, roll back the current transaction and restart the transaction after the user input is supplied. Selbst wenn Benutzer sofort reagieren, ist die menschliche Reaktionszeit bedeutend langsamer als die Geschwindigkeit von Computern.Even if users respond immediately, human reaction times are vastly slower than computer speeds. Alle Ressourcen, die von der Transaktion beansprucht werden, sind für besonders lange Zeit belegt, was zu Blockierungsproblemen führen kann.All resources held by the transaction are held for an extremely long time, which has the potential to cause blocking problems. Wenn Benutzer nicht reagieren, bleibt die Transaktion aktiv und sperrt so lange wichtige Ressourcen, bis der Benutzer reagiert. Dies kann Minuten, sogar Stunden dauern.If users do not respond, the transaction remains active, locking critical resources until they respond, which may not happen for several minutes or even hours.

  • Öffnen Sie nach Möglichkeit keine Transaktion während des Durchsuchens von Daten.Do not open a transaction while browsing through data, if at all possible.
    Transaktionen sollten erst dann gestartet werden, wenn alle vorhergehenden Datenanalysen abgeschlossen sind.Transactions should not be started until all preliminary data analysis has been completed.

  • Achten Sie darauf, dass eine Transaktion so kurz wie möglich ist.Keep the transaction as short as possible.
    Wenn Sie wissen, welche Änderungen vorgenommen werden müssen, starten Sie eine Transaktion, führen Sie die Änderungsanweisungen aus, und führen Sie unmittelbar im Anschluss einen Commit oder Rollback aus.After you know the modifications that have to be made, start a transaction, execute the modification statements, and then immediately commit or roll back. Öffnen Sie die Transaktion erst, wenn es erforderlich ist.Do not open the transaction before it is required.

  • Sie sollten für schreibgeschützte Abfragen gegebenenfalls eine auf Zeilenversionsverwaltung basierende Isolationsstufe verwenden, um die Möglichkeit von Blockierungen zu reduzieren.To reduce blocking, consider using a row versioning-based isolation level for read-only queries.

  • Setzen Sie die niedrigeren Isolationsstufen von Transaktionen sinnvoll ein.Make intelligent use of lower transaction isolation levels.
    Viele Anwendungen können ganz leicht so codiert werden, dass die Isolationsstufe, bei der ein Commit vor dem Lesevorgang ausgeführt sein muss, für die Transaktion verwendet wird.Many applications can be readily coded to use a read-committed transaction isolation level. Nicht alle Transaktionen erfordern die Isolationsstufe SERIALIZABLE.Not all transactions require the serializable transaction isolation level.

  • Setzen Sie die niedrigen Optionen der Cursorparallelität, wie etwa die vollständige Parallelität, sinnvoll ein.Make intelligent use of lower cursor concurrency options, such as optimistic concurrency options.
    Wenn es in einem System relativ unwahrscheinlich ist, dass Updates gleichzeitig vorgenommen werden, kann der Aufwand, der gelegentlich für die Fehlerbehandlung entsteht, wenn Daten nach einem Lesevorgang von einem anderen Benutzer geändert werden, bedeutend geringer sein als der Aufwand, der durch das konsequente Sperren von Zeilen bei jedem Lesen entsteht.In a system with a low probability of concurrent updates, the overhead of dealing with an occasional "somebody else changed your data after you read it" error can be much lower than the overhead of always locking rows as they are read.

  • Während einer Transaktion sollte auf so wenige Daten wie möglich zugegriffen werden.Access the least amount of data possible while in a transaction.
    Dadurch wird die Anzahl der gesperrten Zeilen gesenkt und Konflikte zwischen Transaktionen vermieden.This lessens the number of locked rows, thereby reducing contention between transactions.

Vermeiden von Parallelitäts- und RessourcenproblemenAvoiding concurrency and resource problems

Wenn Sie Parallelitäts- und Ressourcenprobleme vermeiden möchten, sollten implizite Transaktionen sorgfältig verwaltet werden.To prevent concurrency and resource problems, manage implicit transactions carefully. Bei impliziten Transaktionen wird durch die nächste Transact-SQLTransact-SQL-Anweisung nach COMMIT oder ROLLBACK automatisch eine neue Transaktion gestartet.When using implicit transactions, the next Transact-SQLTransact-SQL statement after COMMIT or ROLLBACK automatically starts a new transaction. Dadurch kann eine neue Transaktion geöffnet werden, während die Anwendung Daten durchsucht oder sogar wenn Eingaben des Benutzers erforderlich sind.This can cause a new transaction to be opened while the application browses through data, or even when it requires input from the user. Nach Abschluss der letzten Transaktion, die zum Schutz von Datenänderungen erforderlich ist, sollten Sie die impliziten Transaktionen deaktivieren, bis erneut eine Transaktion benötigt wird, um Datenänderungen zu schützen.After completing the last transaction required to protect data modifications, turn off implicit transactions until a transaction is once again required to protect data modifications. Auf diese Weise kann SQL Server-Datenbank-EngineSQL Server Database Engine den Autocommitmodus verwenden, während die Anwendung Daten durchsucht und Benutzereingaben vorgenommen werden.This process lets the SQL Server-Datenbank-EngineSQL Server Database Engine use autocommit mode while the application is browsing data and getting input from the user.

Wenn die Momentaufnahme-Isolationsstufe aktiviert ist, obwohl eine neue Transaktion keine Sperren beibehält, verhindert außerdem eine Transaktion mit langer Ausführungszeit, dass die alten Versionen aus tempdb entfernt werden.In addition, when the snapshot isolation level is enabled, although a new transaction will not hold locks, a long-running transaction will prevent the old versions from being removed from tempdb.

Verwalten lang andauernder TransaktionenManaging long-running transactions

Eine Transaktion mit langer Ausführungszeit ist eine aktive Transaktion, für die kein Commit bzw. Rollback rechtzeitig ausgeführt wurde.A long-running transaction is an active transaction that has not been committed or roll backed the transaction in a timely manner. Bei Transaktionen, deren Beginn und Ende vom Benutzer gesteuert werden, kann es vorkommen, dass der Benutzer eine Transaktion startet und dann seinen Arbeitsplatz verlässt, während die Transaktion auf eine Reaktion des Benutzers wartet. Dies ist z. B. eine typische Ursache für eine lang andauernde Transaktion.For example, if the beginning and end of a transaction is controlled by the user, a typical cause of a long-running transaction is a user starting a transaction and then leaving while the transaction waits for a response from the user.

Eine Transaktion mit langer Ausführungszeit kann für eine Datenbank schwerwiegende Probleme nach sich ziehen:A long running transaction can cause serious problems for a database, as follows:

  • Wenn eine Serverinstanz heruntergefahren wird, nachdem die aktive Transaktion zahlreiche Änderungen vorgenommen hat, für die kein Commit ausgeführt wurde, kann die Wiederherstellungsphase beim nachfolgenden Neustart erheblich länger dauern als durch die Serverkonfigurationsoption Wiederherstellungsintervall bzw. durch die ALTER DATABASE ... SET TARGET_RECOVERY_TIME-Option angegeben.If a server instance is shut down after an active transaction has performed many uncommitted modifications, the recovery phase of the subsequent restart can take much longer than the time specified by the recovery interval server configuration option or by the ALTER DATABASE ... SET TARGET_RECOVERY_TIME option. Durch diese Option wird die Frequenz aktiver bzw. indirekter Prüfpunkte gesteuert.These options control the frequency of active and indirect checkpoints, respectively. Weitere Informationen zu Prüfpunkttypen finden Sie unter Datenbankprüfpunkte (SQL Server).For more information about the types of checkpoints, see Database Checkpoints (SQL Server).

  • Obwohl durch eine wartende Transaktion möglicherweise nur sehr wenige Protokolldaten generiert werden, wird die Protokollkürzung auf unbestimmte Zeit aufgehalten. Dies führt dazu, dass das Transaktionsprotokoll anwächst und möglicherweise irgendwann voll ist.More importantly, although a waiting transaction might generate very little log, it holds up log truncation indefinitely, causing the transaction log to grow and possibly fill up. Wenn das Transaktionsprotokoll voll ist, kann die Datenbank keine weiteren Updates mehr ausführen.If the transaction log fills up, the database cannot perform any more updates. Weitere Informationen finden Sie im Handbuch zur Architektur und Verwaltung von Transaktionsprotokollen in SQL Server, unter Problembehandlung bei einem vollständigen Transaktionsprotokoll (SQL Server-Fehler 9002) sowie unter Das Transaktionsprotokoll (SQL Server).For more information, see SQL Server Transaction Log Architecture and Management Guide, Troubleshoot a Full Transaction Log (SQL Server Error 9002), and The Transaction Log (SQL Server).

Ermitteln von Transaktionen mit langer AusführungszeitDiscovering long-running transactions

Verwenden Sie eine der folgenden Optionen, um nach lang andauernden Transaktionen zu suchen:To look for long-running transactions, use one of the following:

  • sys.dm_tran_database_transactionssys.dm_tran_database_transactions

    Diese dynamische Verwaltungssicht gibt Informationen zu Transaktionen auf Datenbankebene zurück.This dynamic management view returns information about transactions at the database level. Bei einer Transaktion mit langer Ausführungszeit gehören der Zeitpunkt des ersten Protokolldatensatzes (database_transaction_begin_time), der aktuelle Status der Transaktion (database_transaction_state)und die Protokollfolgenummer (Log Sequence Number, LSN) des ersten Datensatzes im Transaktionsprotokoll (database_transaction_begin_lsn) zu den Spalten von besonderem Interesse.For a long-running transaction, columns of particular interest include the time of the first log record (database_transaction_begin_time), the current state of the transaction (database_transaction_state), and the log sequence number (LSN) of the begin record in the transaction log (database_transaction_begin_lsn).

    Weitere Informationen finden Sie unter sys.dm_tran_database_transactions (Transact-SQL).For more information, see sys.dm_tran_database_transactions (Transact-SQL).

  • DBCC OPENTRAN

    Mithilfe dieser Anweisung können Sie die Benutzer-ID des Transaktionsbesitzers identifizieren. Auf diese Weise können Sie die Quelle der Transaktion ermitteln und die Transaktion ordnungsgemäß beenden (durch ein Commit anstelle eines Rollbacks).This statement lets you identify the user ID of the owner of the transaction, so you can potentially track down the source of the transaction for a more orderly termination (committing it rather than rolling it back). Weitere Informationen finden Sie unter DBCC OPENTRAN (Transact-SQL).For more information, see DBCC OPENTRAN (Transact-SQL).

Beenden einer TransaktionStopping a Transaction

Unter Umständen müssen Sie die KILL-Anweisung ausführen.You may have to use the KILL statement. Verwenden Sie diese Anweisung jedoch sehr vorsichtig, besonders wenn gerade kritische Prozesse ausgeführt werden.Use this statement very carefully, however, especially when critical processes are running. Weitere Informationen finden Sie unter KILL (Transact-SQL).For more information, see KILL (Transact-SQL).

Zusätzliches LesematerialAdditional Reading

Mehraufwand der Zeilenversionsverwaltung Overhead of Row Versioning
Erweiterte Ereignisse Extended Events
sys.dm_tran_locks (Transact-SQL) sys.dm_tran_locks (Transact-SQL)
Dynamische Verwaltungssichten und -funktionen (Transact-SQL) Dynamic Management Views and Functions (Transact-SQL)
Dynamische Verwaltungssichten und Funktionen in Verbindung mit Transaktionen (Transact-SQL)Transaction Related Dynamic Management Views and Functions (Transact-SQL)