Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

SQL Server : Bug sur les colonnes auto incrémentées dans SQL Server 2005 et 2008

Bug qui m'a particulièrement surpris, et qui a mon sens est très sévère pour les bases de données. En effet celui-ci affecte la valeur renvoyée par @@IDENTITY et SCOPE_IDENTITY().

Voir ici pour leur rôle : http://blogs.codes-sources.com/christian/archive/2007/02/23/sql-server-champs-compteur-identity-ou-scope-identity.aspx

Le problème survient quand SQL Server utilise un plan d'exécution parallélisé pour une requête d'insertion. Ce cas n'est heureusement pas le plus fréquent, mais si une requête mets à jour une table utilisée par une vue indexées ou insère une grande quantité de données ce cas devient très probable. Dans ce cas la valeur du dernier incrément renvoyé pour une colonne de type IDENTITY est fausse !

Le bug et les scripts permettant de le reproduire : https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

Ci-dessous un script permettant de reproduire le problème :

USE tempdb
GO

CREATE
FUNCTION dbo.fn_nums(@n AS bigint) RETURNS TABLE AS
RETURN
WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
L4 AS(SELECT 1 AS c FROM L3 AS A, L3 AS B),
L5 AS(SELECT 1 AS c FROM L4 AS A, L4 AS B),
Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L5)
SELECT n FROM Nums WHERE n <= @n
GO

CREATE
TABLE alpha (ident int IDENTITY(1, 1) PRIMARY KEY, value int NOT NULL);
CREATE TABLE beta (Number int NOT NULL PRIMARY KEY);

INSERT beta(Number) SELECT n FROM fn_nums(200000);

DECLARE @var int;
SET @var = 4;

INSERT INTO alpha (value)
SELECT Number FROM beta
WHERE Number BETWEEN 1 AND @var

SELECT scope_identity() AS [scope_identity] ,
        @@identity AS [@@identity],
        @@rowcount AS [@@rowcount],
        ident_current('alpha') AS [ident_current]

SELECT * FROM alpha
GO

DROP
TABLE alpha
DROP TABLE beta
DROP FUNCTION fn_nums
DROP FUNCTION fn_nums

GO

Dans mon cas j'obtiens :

@@rowcount

scope_identity

@@identity

ident_current

4

NULL

NULL

4

Ou 256 à la place de NULL suivant les cas.

Ce problème ne se produit que quand un plan parallèle est utilisé par le moteur, donc ne peut se produire sur SQL Server édition Express. Une manière d'éviter ce bug est de limiter le nombre de processeur avec lesquels travaille SQL Server :

INSERT INTO alpha (value)
SELECT Number FROM beta
WHERE Number BETWEEN 1 AND @var
OPTION(MAXDOP 1)

Pour un correctif plus global sur le serveur :

-- Toutes les requêtes seront executées sur un seul processeur

EXEC sp_configure 'max degree of parallelism', 1
reconfigure

-- On vide le cache des plan d'execution pour que le paramètre définie ci-dessus d'applique à toutes

DBCC freeproccache

Attention à cette méthode vous risquez d'avoir des requêtes s'executant en lecture qui prendront enormement plus de temps !

A vous de mesurer l'impact du bug sur vos applications, s'il y a un par rapport aux corrections qui pourraient éventuellement apportées pour y palier.

En attendant un correctif…

Bonne lecture…

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Publié vendredi 26 décembre 2008 22:07 par christian
Classé sous : ,

Commentaires

Pas de commentaires
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [Refactoring] ReSharper pour Visual Studio 2010 (Preview) par Thomas Jaskula le il y a 6 heures et 6 minutes

- [Refactoring] Analyser vos exceptions avec ReSharper Exceptional par Thomas Jaskula le il y a 7 heures et 20 minutes

- SharePoint 2007 : patterns & practices SharePoint Guidance par Philippe Sentenac [MVP SharePoint] le il y a 20 heures et 59 minutes

- [Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par Etienne Margraff le il y a 21 heures et 56 minutes

- MVP[Gribouillon].AddYear par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le il y a 22 heures et 11 minutes

- Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par David REI le 07-02-2009, 23:38

- C’est la crise ? Bah pourquoi cramer du budget pub alors ? par Nix's Blog le 07-02-2009, 15:31

- Soyons MVP ! par TheSaib .NET blog le 07-02-2009, 12:15

- SharePoint : Gestion des Erreurs 6398, 7076 et 6482 par Blog Technique de Romelard Fabrice le 07-02-2009, 11:53

- EF avec WPF par Matthieu MEZIL le 07-02-2009, 10:18