Nous voyons certains pernicieuse, mais rare, impasse des conditions dans le Débordement de la Pile de SQL Server 2005 bases de données.
J'ai attaché le profiler, configurer une trace de profil à l'aide de cet excellent article sur la résolution des blocages, et capturé un tas d'exemples. La chose étrange est que le blocage d'écriture est toujours la même:
UPDATE [dbo].[Posts]
SET [AnswerCount] = @p1, [LastActivityDate] = @p2, [LastActivityUserId] = @p3
WHERE [Id] = @p0
L'autre blocage de déclaration varie, mais il est généralement une sorte de trivial, de la simple lecture de la table posts. Ce on obtient toujours tué dans l'impasse. Voici un exemple
SELECT
[t0].[Id], [t0].[PostTypeId], [t0].[Score], [t0].[Views], [t0].[AnswerCount],
[t0].[AcceptedAnswerId], [t0].[IsLocked], [t0].[IsLockedEdit], [t0].[ParentId],
[t0].[CurrentRevisionId], [t0].[FirstRevisionId], [t0].[LockedReason],
[t0].[LastActivityDate], [t0].[LastActivityUserId]
FROM [dbo].[Posts] AS [t0]
WHERE [t0].[ParentId] = @p0
Pour être parfaitement clair, on ne voit pas écrire / écrire des blocages, mais en lecture / écriture.
Nous avons un mélange de LINQ et des requêtes SQL paramétrées pour le moment. Nous avons ajouté with (nolock)
de toutes les requêtes SQL. Cela peut avoir aidé certains. Nous avons également eu un seul (très) mal écrit insigne de la requête que je fixe hier, qui a été prise à la hausse de 20 secondes pour s'exécuter à chaque fois, et était en cours d'exécution, chaque minute sur le dessus de cela. J'espérais que c'était la source de certains problèmes de verrouillage!
Malheureusement, j'ai eu une autre erreur de blocage d'environ 2 heures. Même symptômes, même coupable de l'écriture.
Vraiment étrange, c'est que le verrouillage en écriture instruction SQL que vous voyez ci-dessus est d'une partie très spécifique chemin d'accès du code. C'est seulement exécutée lorsqu'une nouvelle réponse est ajouté à une question, il met à jour le parent en question avec la nouvelle réponse comte et de la dernière date/de l'utilisateur. C'est, évidemment, pas que la commune par rapport au nombre imposant de lectures que nous faisons! Aussi loin que je peux dire, nous ne faisons pas de grands nombres d'écrit n'importe où dans l'application.
Je me rends compte que NOLOCK est une sorte de marteau géant, mais la plupart des requêtes, nous courons ici n'ont pas besoin d'être précis. Allez-vous les soins si votre profil d'utilisateur est à quelques secondes de la date?
À l'aide de NOLOCK avec Linq est un peu plus difficile, car Scott, Hanselman discute ici.
Nous sommes en train de flirter avec l'idée de l'utiliser
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
sur la base de la base de données de contexte, de sorte que tous nos requêtes LINQ ont ce jeu. Sans cela, nous aurions à envelopper chaque LINQ appel que nous faisons (ainsi, la simple lecture, ce qui est la grande majorité d'entre eux) dans un 3-4 ligne de transaction de bloc de code, ce qui est laid.
Je suppose que je suis un peu frustré que trivial lit dans SQL 2005 impasse sur l'écrit. J'ai pu voir écrire/écrire des blocages d'être un énorme problème, mais lit? Nous ne sommes pas de l'exécution d'un site bancaire ici, nous n'avons pas besoin d'une exactitude parfaite à chaque fois.
Des idées? Pensées?
Êtes-vous de l'instanciation d'un LINQ to SQL DataContext de l'objet, pour chaque opération, ou vous êtes peut-être à partager le même contexte statique pour tous vos appels?
Jeremy, nous sommes le partage d'une statique datacontext dans le Contrôleur de base pour la plupart:
private DBContext _db;
/// <summary>
/// Gets the DataContext to be used by a Request's controllers.
/// </summary>
public DBContext DB
{
get
{
if (_db == null)
{
_db = new DBContext() { SessionName = GetType().Name };
//_db.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}
return _db;
}
}
Recommandez-vous de nous créer un nouveau contexte pour chaque Contrôleur, ou par Page, ou .. plus souvent?