IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Question sur le fonctionnement des jobs en cas d'erreur


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut Question sur le fonctionnement des jobs en cas d'erreur
    Bonjour,

    Je rencontre un phénomène que je ne comprends pas...

    J'ai un job d'importation d'une vieille DB non normalisée dans une nouvelle DB normalisée.

    Ce job crée un curseur avec les lignes de l'ancienne DB (qui n'est en fait constituée que d'une seule table) et les traite une à une pour les répartir dans les tables appropriée de la nouvelle DB.

    Vu l'état de la vieille DB, vous vous doutez qu'il y a pas mal d'incohérence et donc que le job se plante de temps en temps. En général, pas de souci, je détecte le problème, corrige la donnée dans la vieille DB pour retrouver qqch de cohérent et ça repart sans souci.

    Seulement ici, quand je regarde l'erreur dans le historique du job, l'erreur rapportée est une clef alternative dupliquée dans une table. En effet, je retrouve bien cela dans la vieille DB mais ce que je ne comprends pas, c'est pourquoi les 10 lignes se trouvant après la ligne fautive ont été traité par le job ? Le curseur a bien entendu une clause order by qui m'assure l'ordre dans lequel les lignes sont traitées.

    Est-ce normal qu'un job ne s'arrête tout de suite après avoir rencontré une erreur ? Y a-t-il quelque chose à paramétrer ?

    Voici le code du job (qui n'est constitué que d'un step) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    SET ANSI_WARNINGS OFF;
     
    DECLARE @SEQNRHIST    INT;
    DECLARE @BARCODE    VARCHAR(13);
    DECLARE @DATE        DATETIME;
    DECLARE @ACTION        VARCHAR(1);
    DECLARE    @ORIGIN        INT;
    DECLARE @DESTTYPE    INT;
    DECLARE    @DEST        INT;
    DECLARE @VALUE        INT;
    DECLARE    @SALETYPE    INT;
    DECLARE    @USERTYPE    INT;    
     
    DECLARE @GFT_ID        INT;
    DECLARE @STR_ID        INT;
    DECLARE @DOS_ID        INT;
    DECLARE @DECIMAL_VALUE    DECIMAL(6,2);
    DECLARE @TMP        VARCHAR(100);
    DECLARE @TRN_TILL    SMALLINT;
    DECLARE @TRN_TICKET    SMALLINT;
    DECLARE @USERNAME    VARCHAR(50);
     
    DECLARE C CURSOR FOR
     
    SELECT
            SEQNRHIST,
            BARCODE,
            DATTIM,
            ACTION,
            ORIGIN,
            DESTTYPE,
            DEST,
            VALUE,
            SALETYPE,
            USERTYPE
    FROM
            DBO.T_CHEQUE_ACHAT_HISTORY
    ORDER BY
            SeqNrHist,
            Barcode,
            DatTim
     
    OPEN C;
     
    FETCH NEXT FROM C INTO @SEQNRHIST, @BARCODE, @DATE, @ACTION, @ORIGIN, @DESTTYPE, @DEST, @VALUE, @SALETYPE, @USERTYPE;
     
    WHILE @@FETCH_STATUS = 0
    BEGIN
        --ON RECUPERE L'ID DU GIFT
        EXEC TMP_UP_CREATE_GIFT_IF_NOT_EXISTS @BARCODE, @GFT_ID OUTPUT, @VALUE;
     
        --ON NOTE LA LIGNE EN COURS DE TRAITEMENT POUR IDENTIFIER SI PLANTAGE
        UPDATE DBO.T_CURRENT_LINE_PROCESSING_CLP
        SET
                SEQNRHIST = @SEQNRHIST,
                BARCODE = @BARCODE,
                ACTION = @ACTION
     
        --ON DEFINIT SI L'UTILISATEUR EST NORMAL OU ADMIN
        IF @USERTYPE <> 0
            SET @USERNAME = 'ADMIN';
        ELSE
            SET @USERNAME = 'NORMAL';
     
        --UTILISE A LA CAISSE (TTR_ID = 1)
        IF @ACTION = 'P'
        BEGIN
            --ON RECUPERE L'ID DU MAGASIN
            SET @ORIGIN = @ORIGIN * 10000
            IF @ORIGIN = 0
                SET @ORIGIN = 17
            ELSE 
                EXEC TMP_UP_GET_STORE_ID @ORIGIN, @STR_ID OUTPUT;
     
            --ON RECUPERE LA CAISSE ET LE TICKET
            IF @USERTYPE <> 0 --SI L'UTILISATION EST SIMULEE PAR UN ADMIN --> CAISSE ET TICKET = 0
            BEGIN
                SET @TRN_TICKET = 0;
                SET @TRN_TILL = 0;
            END
            ELSE
            BEGIN
                SET @TMP =  RIGHT('000000'+CAST(@DEST AS VARCHAR(6)),6);
                SET @TRN_TILL = CAST(LEFT(@TMP,2) AS SMALLINT);
                SET @TRN_TICKET = CAST(RIGHT(@TMP,4) AS SMALLINT);
            END
     
            --ON INSERE LA TRANSACTION
            SET @DECIMAL_VALUE = CAST(@VALUE AS DECIMAL(10,2)) / 100;
            INSERT INTO DBO.T_TRANSACTION_TRN(    TTR_ID, GFT_ID, STR_ID, TRN_DATE, TRN_TILL, TRN_TICKET, TRN_VALUE, TRN_CREATED_BY)
            VALUES(1, @GFT_ID, @STR_ID, @DATE, @TRN_TILL, @TRN_TICKET, @DECIMAL_VALUE, @USERNAME);
        END
     
        FETCH NEXT FROM C INTO @SEQNRHIST, @BARCODE, @DATE, @ACTION, @ORIGIN, @DESTTYPE, @DEST, @VALUE, @SALETYPE, @USERTYPE;
    END
     
    CLOSE C;
    DEALLOCATE C;
    Je n'ai laissé que le le traitement de l'action qui provoque l'erreur. (le code complet se trouve dans le fichier en pièce jointe).

    La clef alternative portant sur les colonnes GFT_ID et TRN_DATE où GFT_ID est l'id du gift qui subit la transaction et TRN_DATE est la date de la transaction. A ce niveau-là, pas de souci, je sais comment régler le problème mais j'aimerais comprendre pourquoi les lignes se trouvant après dans le curseur par rapport à la ligne fautive sont traitées.

    Merci d'avance.
    Fichiers attachés Fichiers attachés

  2. #2
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    N'avez-vous pas une autre erreur derrière qui mettrait fin à la transaction ?

    Pour que votre transaction prenne systématiquement fin en cas d'erreur, vous pouvez spécifier un SET XACT_ABORT ON

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 448
    Par défaut
    Est ce que vous n'insérez pas une ligne, puis 10 autres et finalement à nouveau une ligne qui fait doublon avec la première ?
    Ensuite vous seriez convaincu que le programme a planté à l'insertion de la première ligne.

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    @aieeeuuuu : Un job ne s'arrête pas directement à la première rencontrée ?

    @Sergejack : Non, le curseur traite les lignes une par une. Du moins, c'est ce que je crois ^^. C'est important qu'il traite les lignes les unes après les autres et dans l'ordre indiquée par la clause order by sans quoi, j'aurais des problèmes de cohérences.

    La suite n'est que pure spéculation...

    Est-ce qu'il est possible que le curseur traite plusieurs lignes en parallèles pour gagner du temps ?

    J'ai déjà remarqué quand j'essaie d'exécuter une requête qui provoque une erreur, il y a un petit délai avant de recevoir le message d'erreur alors que lorsque tout va bien, la confirmation est instantanée. Serait-il possible que durant le délai nécessaire au renvoi de l'erreur, le job ait continuée à traiter les lignes suivantes ?

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    @aieeeuuuu : Un job ne s'arrête pas directement à la première rencontrée ?
    Pas forcément, et a priori pas sur une violation de contrainte d'unicité : sauf erreur de ma part, l'instruction en cours est annulée, mais le traitement continu à l'instruction suivante.

    Je vois en revanche dans votre cartouche que vous avez des trigger. En cas d'erreur dans un trigger par contre, le lot complet peut être arrêté, et la transaction en cours annulée.

    Enfin, je crois que vous avez mal interprété ce que vous a dit sergejack :
    si dans vos données vous avez :
    1 - A
    2 - B
    3 - C
    4 - D
    5 - B
    6 - F
    donc avec B qui est dupliqué.
    Peut etre vous attendez vous a ce qu'il n'y ait que la ligne 1 d'insérée, et que ça plante à la ligne 2, or c'est lors du traitement de ligne ligne 5 que l'erreur arrivera... les lignes 3 et 4 seront correctement traitées, alors qu'elles se trouvent après une ligne contenant la clef dupliquée.

  6. #6
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Pas forcément, et a priori pas sur une violation de contrainte d'unicité : sauf erreur de ma part, l'instruction en cours est annulée, mais le traitement continu à l'instruction suivante.
    Ah, c'est ennuyeux ça... Il va donc falloir que j'ajoute l'instruction que vous avez donnée pour forcer l'arrêt lors d'une erreur.
    Citation Envoyé par aieeeuuuuu Voir le message
    Je vois en revanche dans votre cartouche que vous avez des trigger. En cas d'erreur dans un trigger par contre, le lot complet peut être arrêté, et la transaction en cours annulée.
    C'est le comportement attendu. Histoire de pouvoir investiguer sur l'erreur rencontrée, la corrigée et faire en sorte que cela n'arrive plus.

    Citation Envoyé par aieeeuuuuu Voir le message
    Enfin, je crois que vous avez mal interprété ce que vous a dit sergejack :
    si dans vos données vous avez :


    donc avec B qui est dupliqué.
    Peut etre vous attendez vous a ce qu'il n'y ait que la ligne 1 d'insérée, et que ça plante à la ligne 2, or c'est lors du traitement de ligne ligne 5 que l'erreur arrivera... les lignes 3 et 4 seront correctement traitées, alors qu'elles se trouvent après une ligne contenant la clef dupliquée.
    J'avais bien compris. La ligne 2 n'a évidemment aucune raison de provoquée une erreur. Mais vous me faites doutes... P-e ai-je mal regardé lors de mon investigation suite à cette erreur. Mais si j'avais bien les yeux en face des trous à ce moment-là, ce que j'ai vu c'est :
    1 - A
    2 - B
    3 - C
    ...
    21 - D
    22 - B
    23 - F
    24 - G
    25 - H
    26 - I
    27 - J
    28 - K
    29 - L
    30 - M
    31 - N
    Avec dans le message d'erreur, la valeur de clef que le job tente de dupliquée et dans la table qui trace la ligne en cours de traitement, le numéro de la ligne 31.

Discussions similaires

  1. Question sur le fonctionnement des "fichiers ouverts"
    Par Lung dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 17/03/2012, 16h28
  2. Question sur le fonctionnement des "fichiers ouverts"
    Par Lung dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 08/03/2012, 09h33
  3. Question sur le fonctionnement des liste lié
    Par DeeVoiD dans le forum Ruby on Rails
    Réponses: 2
    Dernier message: 19/05/2009, 13h14
  4. Question sur le fonctionnement des sessions
    Par kuja2053 dans le forum Langage
    Réponses: 3
    Dernier message: 26/06/2007, 19h15
  5. [EJB] Question sur le fonctionnement des EJB
    Par derek.mf dans le forum Java EE
    Réponses: 9
    Dernier message: 28/03/2006, 12h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo