Auslöser, der einen Deadlock verursacht?

8

Ich bin in einen Deadlock geraten, nachdem ich einen Trigger hinzugefügt habe. Es gibt eine Tabelle UserBalanceHistory , die für jede Transaktion eine Zeile und eine Amount -Spalte enthält. Ein Trigger wurde hinzugefügt, um die Spalte Amount zu summieren und das Ergebnis in die verknüpfte Tabelle User , Balance zu setzen.

%Vor%

Ich habe auch READ_COMMITTED_SNAPSHOT :

aktiviert %Vor%

Ich habe einen parallelen Prozess ausgeführt, der UserBalanceHistory -Einträge erstellt, anscheinend, wenn er zur gleichen Zeit an demselben User arbeitet, tritt der Deadlock auf. Vorschläge?

    
Josh M. 08.06.2011, 17:04
quelle

2 Antworten

2

Der Deadlock tritt auf, weil Sie auf UserBalanceHistory zugreifen - & gt; UserBalanceHistory - & gt; Benutzer, während ein anderes Update Benutzer ist - & gt; BenutzerBalanceHistory. Es ist komplexer als das wegen der Sperrgranularität und Indexsperren etc.

Die Ursache ist wahrscheinlich ein Scan von UserBalanceHistory für UserID und Betrag. Ich hätte einen Index auf (UserID) INCLUDE (Amount) auf UserBalanceHistory, um dies zu ändern

SNAPSHOT-Isolierungsmodelle können immer noch blockieren: Es gibt Beispiele dafür ( One ) , Zwei

Schließlich, warum nicht alles in einem, um verschiedene und mehrere Update-Pfade zu vermeiden?

%Vor%     
gbn 08.06.2011 17:13
quelle
0

Ändern Sie den gruppierten Schlüssel zur Benutzer-ID in Ihrer Tabelle UserBalanceHistory, und löschen Sie den nicht gruppierten Index, da Sie die Benutzer-ID für den Zugriff auf die Tabelle verwenden. Es gibt keinen Grund, eine Identitätsspalte für den gruppierten Index zu verwenden. Clustered-Index verwendet werden und dann aus dem Clustered-Index gelesen werden, um den Geldwert zu ändern. Clustered-Indizes eignen sich am besten für die Bereichssuche. Dies ist der Fall, wenn Sie den Saldo addieren. Ihre aktuelle Situation kann dazu führen, dass SQL jede Datenseite in der Tabelle anfordert, nur um die Zahlungen des Benutzers zu erhalten. Eine Fragmentierung im Clustered-Index wird durch die (sp) verlinkten Seiten für eine einzelne Benutzer-ID ausgeglichen. Das Ändern des Clusters und das Löschen des Nicht-Clusters spart Zeit und Speicherplatz.
Führen Sie keine gespeicherten Prozeduren vom Trigger aus, da dies die ausgelöste Tabelle sperrt, während der SP beendet ist.

Die Balance-Tabelle könnte aus einer Ansicht mit einer berechneten Spalte erstellt werden (SO-Link hier ) in der UserBalanceHistory-Tabelle.

In einem Entwicklungssystem testen und dann erneut testen!

    
RC_Cleland 08.06.2011 20:58
quelle