web-dev-qa-db-fra.com

La transaction SQL a été bloquée

Parfois, j'obtiens ce genre d'exception sur un serveur SQL peu occupé:

Transaction (Process ID 57) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Line number: 1
Error Number: 1205
Procedure: 
Server name: P01
Error Source: .Net SqlClient Data Provider
Error State: 47

Je ne suis pas en mesure de le reproduire. J'ai essayé d'exécuter plusieurs requêtes de différents clients en même temps, mais cela ne s'est pas affiché. Quelle est la meilleure façon de gérer ce type de problème lorsqu'il se produit dans la procédure ou dans le déclencheur? Je veux dire, comment relancer la transaction?

Comment le faire lorsqu'une exception se produit dans la procédure appelée à partir du déclencheur, qui a été appelée par l'insertion effectuée par une procédure (c'est-à-dire: procédure01 -> insertion -> déclencheur -> procédure02!)

26
Piotr Salaciak

Je suggère que vous abordiez le problème sous deux angles.

  1. Trap or Catch Deadlock Errors afin que vous puissiez réexécuter la transaction choisie comme Deadlock Victim par SQL Server moteur de base de données.

  2. Découvrez ce qui cause vos événements de blocage. Vous pouvez le faire de deux manières, soit exécutez un SQL Server Profiler Trace pour intercepter et enregistrer le blocage Événement ou vous pouvez activer certains SQL Server Trace Flags qui enregistrera les détails de l'événement de blocage dans le journal des erreurs SQL Server.

Dans la grande majorité des cas, vous pouvez identifier la cause de vos événements de blocage et remédier à la situation soit par un changement structurel dans le schéma de la base de données, soit par une logique changer le code impliqué/responsable de l'événement Deadlock.

Pour en savoir plus, consultez:

J'espère avoir répondu à votre question, mais faites-moi savoir si je peux vous aider davantage.

39
John Sansom

Configurez une trace SQL côté serveur qui capture les événements de graphique de blocage afin que vous puissiez consulter le fichier .trc avec SQL Profiler. De cette façon, vous pouvez avoir quelque chose en place pour pouvoir résoudre tout blocage. J'ai fourni le code ci-dessous. Vous devrez modifier le chemin du fichier selon les besoins. Ce serait une bonne idée de configurer ce script pour qu'il s'exécute au démarrage de SQL Server.

FYI - Un grand nombre de choses différentes peuvent provoquer un blocage, l'un d'eux manquant d'index.

declare @rc int
declare @TraceID int
declare @maxfilesize bigint
set @maxfilesize = 10 
declare @dtName nvarchar(50)
select @dtName=(N'I:\Trace_Logs\DeadLockTrace'+ convert(nvarchar(8),getdate(),112))


-- Please replace the text InsertFileNameHere, with an appropriate
-- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
-- will be appended to the filename automatically. If you are writing from
-- remote server to local drive, please use UNC path and make sure server has
-- write access to your network share

exec @rc = sp_trace_create @TraceID output, 2, @dtName, @maxfilesize, NULL ,365

if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 148, 11, @on
exec sp_trace_setevent @TraceID, 148, 51, @on
exec sp_trace_setevent @TraceID, 148, 4, @on
exec sp_trace_setevent @TraceID, 148, 12, @on
exec sp_trace_setevent @TraceID, 148, 14, @on
exec sp_trace_setevent @TraceID, 148, 26, @on
exec sp_trace_setevent @TraceID, 148, 60, @on
exec sp_trace_setevent @TraceID, 148, 64, @on
exec sp_trace_setevent @TraceID, 148, 1, @on
exec sp_trace_setevent @TraceID, 148, 41, @on
exec sp_trace_setevent @TraceID, 25, 7, @on
exec sp_trace_setevent @TraceID, 25, 15, @on
exec sp_trace_setevent @TraceID, 25, 55, @on
exec sp_trace_setevent @TraceID, 25, 8, @on
exec sp_trace_setevent @TraceID, 25, 32, @on
exec sp_trace_setevent @TraceID, 25, 56, @on
exec sp_trace_setevent @TraceID, 25, 64, @on
exec sp_trace_setevent @TraceID, 25, 1, @on
exec sp_trace_setevent @TraceID, 25, 9, @on
exec sp_trace_setevent @TraceID, 25, 25, @on
exec sp_trace_setevent @TraceID, 25, 41, @on
exec sp_trace_setevent @TraceID, 25, 49, @on
exec sp_trace_setevent @TraceID, 25, 57, @on
exec sp_trace_setevent @TraceID, 25, 2, @on
exec sp_trace_setevent @TraceID, 25, 10, @on
exec sp_trace_setevent @TraceID, 25, 26, @on
exec sp_trace_setevent @TraceID, 25, 58, @on
exec sp_trace_setevent @TraceID, 25, 3, @on
exec sp_trace_setevent @TraceID, 25, 11, @on
exec sp_trace_setevent @TraceID, 25, 35, @on
exec sp_trace_setevent @TraceID, 25, 51, @on
exec sp_trace_setevent @TraceID, 25, 4, @on
exec sp_trace_setevent @TraceID, 25, 12, @on
exec sp_trace_setevent @TraceID, 25, 52, @on
exec sp_trace_setevent @TraceID, 25, 60, @on
exec sp_trace_setevent @TraceID, 25, 13, @on
exec sp_trace_setevent @TraceID, 25, 6, @on
exec sp_trace_setevent @TraceID, 25, 14, @on
exec sp_trace_setevent @TraceID, 25, 22, @on
exec sp_trace_setevent @TraceID, 59, 55, @on
exec sp_trace_setevent @TraceID, 59, 32, @on
exec sp_trace_setevent @TraceID, 59, 56, @on
exec sp_trace_setevent @TraceID, 59, 64, @on
exec sp_trace_setevent @TraceID, 59, 1, @on
exec sp_trace_setevent @TraceID, 59, 21, @on
exec sp_trace_setevent @TraceID, 59, 25, @on
exec sp_trace_setevent @TraceID, 59, 41, @on
exec sp_trace_setevent @TraceID, 59, 49, @on
exec sp_trace_setevent @TraceID, 59, 57, @on
exec sp_trace_setevent @TraceID, 59, 2, @on
exec sp_trace_setevent @TraceID, 59, 14, @on
exec sp_trace_setevent @TraceID, 59, 22, @on
exec sp_trace_setevent @TraceID, 59, 26, @on
exec sp_trace_setevent @TraceID, 59, 58, @on
exec sp_trace_setevent @TraceID, 59, 3, @on
exec sp_trace_setevent @TraceID, 59, 35, @on
exec sp_trace_setevent @TraceID, 59, 51, @on
exec sp_trace_setevent @TraceID, 59, 4, @on
exec sp_trace_setevent @TraceID, 59, 12, @on
exec sp_trace_setevent @TraceID, 59, 52, @on
exec sp_trace_setevent @TraceID, 59, 60, @on

-- Set the Filters
declare @intfilter int
declare @bigintfilter bigint

-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error: 
select ErrorCode=@rc

finish: 
go
5
Quantum Elf

J'ai résolu comme un problème en utilisant le niveau d'isolement Read Committed.

2
trueboroda

Je suis résolu cette erreur par:

  1. Redémarrez SQL Server
  2. Exécuter la requête:

    UTILISER [master] ALTER DATABASE nom_database SET MULTI_USER AVEC ROLLBACK IMMEDIATE

Bonne chance!

0
IT Vlogs