Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > ETL > Talend
Talend Forum d'entraide sur Talend (Talend Open Studio, ...). Avant de poster --> FAQ Talend, Tutoriels Talend
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 03/03/2011, 12h05   #1
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Par défaut Talende Commit Rollback Enregistrement par Enregistrement

Bonjour à tous,

je tourne en rond depuis un moment sur une problématique de Commit/Rollback sur Talend.

Je lis une table source qui contient des informations suivantes:
- NUMERO_COMMANDE
- NUMERO_LIGNE_COMMANDE
- CLIENT
- NOM_CLIENT
- ARTICLE
- LIBELLE ARTICLE
- QTE_COMMANDEE
- PRIX_UNITAIRE

A partir de cette table je dois en alimenter 2 autres:
La table COMMANDE:
- NUMERO_COMMANDE
- CLIENT
- NOM_CLIENT

La table LIGNE_COMMANDE:
- NUMERO_COMMANDE
- NUMERO_LIGNE_COMMANDE
- ARTICLE
- LIBELLE ARTICLE
- QTE_COMMANDEE
- PRIX_UNITAIRE

Le traitement doit se réaliser enregistrement par enregistrement. S'il n'y a pas d'erreur lors de l'insertion dans COMMANDE et LIGNE_COMMANDE je voudrais faire un commit sur l'enregistrement et passer au suivant. S'il y a une erreur lors de l'insertion de l'enregistrement dans COMMANDE ou LIGNE_COMMANDE je voudrais faire un rollback de la ligne en erreur mais continuer le traitement.

Merci pour vos propositions.
Images attachées
Type de fichier : jpg Commit.jpg (19,8 Ko, 19 affichages)
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2011, 15h47   #2
Membre habitué
 
Inscription : août 2005
Messages : 117
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2005
Messages : 117
Points : 145
Points : 145
Bonjour,

pourrais-tu indiquer la version de Talend que tu utilises (TIS / TOS et numéro de version)

Citation:
Envoyé par enricococo40 Voir le message
Le traitement doit se réaliser enregistrement par enregistrement.
Est-ce vraiment une nécessité ?
Si la transaction est au niveau de tout le flux, est-ce vraiment un problème ?
As-tu beaucoup de lignes dans le flux source ?

Voilà une solution mais je ne te la conseilles pas pour les raisons suivantes :
> C'est du bricolage
> C'est vraiment pas performant
> Il y a un risque d'outOfMemory selon le nombre de thread créés (même en décochant multithread dans le tRunJob). 9a plante chez moi pour quelques milliers de lignes. Après, tu peux toujours jouer sur la JVM ou sur la mémoire allouée à chaque thread (la baisser) pour augmenter tes chances (mais le risque est de se retrouver avec un StackOverflowError à la place).

> Job 1 :
Lecture source (tOracleInput) --> Main vers un tRunJob (vers Job 2) qui a pour variables les champs de ton flux (Bien penser à décocher l'exécution multithread)

> Job 2 :
Connection --> Transformation des variables en flux () --> Transformation du flux (tMap) --> Écriture dans tes deux tables (tOracleOutput) --> Commit --> Fermeture connection

Je posterai plus tard un screen des jobs. Je vais quand même voir si je ne trouve pas quelque chose de plus pérenne.
tetsu no tama est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/03/2011, 16h45   #3
Membre habitué
 
Inscription : août 2005
Messages : 117
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2005
Messages : 117
Points : 145
Points : 145
Bon, j'ai tenté de faire ça en un seul job pour éviter les problématiques citées ci-dessus.

Ça donne quelque chose comme ce que j'ai mis en pièce-jointe.

Ça a l'air de fonctionner, mais je n'ai pas accès tout de suite à une base où je peux faire des tests sur ce genre de choses.

Si tu as besoin de détails sur la configuration des divers composants.
Images attachées
Type de fichier : jpg job2.JPG (25,1 Ko, 25 affichages)
tetsu no tama est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 10h43   #4
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Bonjour,

merci tetsu no tama pour tes réponses. Je travaille sur TIS avec la version 4.0 de Talend.

Oui, je suis obligé de faire un traitement enregistrement par enregistrement. Le projet que je suis en train de traiter est la reprise d'un flux de données issus de Scribe (outil de migration, traitement des données). Les jobs talends développés doivent être iso fonctionnels.

Le nombre de lignes dans certains des traitements sera certainement conséquent (> 1 000 000 de lignes dans certains cas).

J'ai déjà réussi à me faire un job comme proposé dans ta première solution. (voir pièces jointes). Cette méthode fonctionne parfaitement avec un faible volume de données. Mais elle me pose 2 problèmes et avec ce que tu as dis peut-être 3:
- le 1er mais qui n'est pas si grave et que ça me dérange d'avoir 2 Jobs là ou l'ancien produit permettait de tout faire dans un traitement. Bon, c'est un point sur lequel je peux me débrouiller.
- le 2ème point est que certaines des tables sources que je traite ont 180 attributs!!! J'ai une 10ènes de lots à reprendre qui sont comme ça, et la perspective de devoir créer 180 variables m'ennuie un peu.
- le 3ème, c'est le risque de non performance que tu évoques. Je n'ai pas fait de test avec une forte volumétrie.

C'est pour tout ça que je voulais tout faire dans un seul Job.

Je vais faire un test sur ta deuxième proposition et je te tiens au courant.


Merci
Images attachées
Type de fichier : jpg JOBPERE.jpg (32,4 Ko, 21 affichages)
Type de fichier : jpg JOBFILS.jpg (26,4 Ko, 17 affichages)
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 11h19   #5
atb
Membre chevronné
 
Homme
Inscription : novembre 2004
Messages : 569
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : Autre

Informations forums :
Inscription : novembre 2004
Messages : 569
Points : 696
Points : 696
Bonjour,
Dans les paramètres du composant tOracleOutput, onglet Advanced settings tu as le paramètres "Commit every " qui est par défaut positionner à 10000. TU peux le mettre à 1. Ceci augmentera la charge coté oracle bien sûr.

Mais pour l'utiliser il faut virer le oracleconnect, commit et rollback.

Tu peux récupérer les lignes rejeter à partir du OracleOuput. Il a deux flux: main et reject. Moi je les récupère dans un fichier CSV et j'envoie par mail. L'avantage est que ça ne plante pas le job. Mais si en cas d'errer tu veux tout arrêter , tu peux cocher "Die on error"
atb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 12h12   #6
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Bonjour,

Peut-être que la solution pourrait venir de la gestion des erreurs avec les composants tWarning ou tDie.

Dans l'exemple que j'ai cité en haut, je pourrai mettre le rollback et le commit après le composant d'insertion sur la table LIGNE_COMMANDE.
S'il n'y a pas eu d'erreur (errorCode == null) lors de l'insertion dans les premières tables le COMMIT s'exécute.
S'il y a eu une erreur alors on fait le Rollback mais il faudrait remettre le errorCode à null. Est-ce possible? Je ne sais pas trop comment faire car je ne connais pas bien java...

Le seul Hic avec cette solution c'est que je ne suis pas sûr de l'ordre d'exécution de talend.

Est-ce qu'il va commencer par insérer toutes les lignes du flux dans la première table (COMMANDE) et ensuite toutes les lignes du flux dans la seconde table (LIGNE_COMMANDE) (Dans ce cas là, ma solution du test des erreurs tombe à l'eau) ou va-t-il traiter 1 enregistrement dans COMMANDE, 1 enregistrement dans LIGNE_COMMANDE, etc..? Les tests que j'ai réalisé avec des traces en sortie de chacun des composants me laisse espérer que la deuxième solution est la bonne. Mais rien ne m'assure que cette réaction sera toujours la même.

A suivre...
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 14h23   #7
Membre habitué
 
Inscription : août 2005
Messages : 117
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2005
Messages : 117
Points : 145
Points : 145
Mais ta solution ne garantie pas que la transaction porte sur l'ensemble :
ligne_commande / commande. Seulement que, si les lignes de commandes sont bien insérées, tu envois le flux commande vers le tOracleOutput. Quid si l'insertion de ta commande plante ?
tetsu no tama est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 16h16   #8
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Une piste,

J'essaie de gérer mon commit et mon rollback avec une variable de contexte "codeErreur" qui devrait être mise à jour lorsqu'il y a un rejet sur une des tables où je fais l'insertion.

Le principe:
- à chaque itération, le composant tjavaflex met la variable de contexte codeErreur à 0
- après chaque insertion, s'il y a rejet, je mets cette variable de contexte à 1
- lors l'itération est terminé je teste ma variable. Si elle est égale à 0 alors commit, si elle est égale à 1 alors rollback.

Problème, à chaque passage dans TEST1 ou TEST2 il y a un flux de rejet. Ce qui fait que ma variable est toujours égale à 1, donc rollback à chaque coup.
Quelqu'un aurait il une explication, sachant que je ne peux pas mettre mon composant en erreur (je ne veux pas sortir du job).

Merci pour votre coup de main.
Images attachées
Type de fichier : jpg JOBROLLBACK.jpg (39,6 Ko, 14 affichages)
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 17h00   #9
atb
Membre chevronné
 
Homme
Inscription : novembre 2004
Messages : 569
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : Autre

Informations forums :
Inscription : novembre 2004
Messages : 569
Points : 696
Points : 696
Sur oracle il y a des foreignKey. Tu les positionne sur Commande Line par rapport à commande et client.

Si l'insertion ne passe pas au niveau de commande et client c'est oracle qui rejete la ligne sur lignecommande.

Dans Talend tu ne gère pas ça. Juste récupère les lignes rejetées
atb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2011, 13h55   #10
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Bonjour,

Je n'ai pas le droit de modifier la structure de la base de données.
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2011, 17h40   #11
Membre habitué
 
Inscription : août 2005
Messages : 117
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : août 2005
Messages : 117
Points : 145
Points : 145
atb, ta solution est effectivement très bien mais elle ne permet pas de garantir que la transaction complète s'est bien déroulée.

Si on se base uniquement sur les rejets liés à des erreurs de FK :

1 > insérer les commandes
2 > insérer les lignes de commandes (Rejets si la FK ne correspond pas à une PK de commande)

Mais, si un plantage survient au moment de l'insertion des lignes de commandes , alors, tu auras déjà bel et bien inséré une commande incomplète.

Si j'ai bien compris le besoin de enricococo40, la transaction doit garantir que l'ensemble : "commande / lignes de commande" est Ok.
tetsu no tama est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2011, 18h02   #12
atb
Membre chevronné
 
Homme
Inscription : novembre 2004
Messages : 569
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 28
Localisation : Autre

Informations forums :
Inscription : novembre 2004
Messages : 569
Points : 696
Points : 696
Alors je ne comprends pas, pourquoi on insert pas dans les tables Commande et client. Tout en récupérant les rejets.

Ensuite on insert dans la table ligne commande. Puis on supprime les lignes de cette dernier, qui correspondent aux lignes rejetées des deux premières tables .

Ensuite on supprime, par exemple de la table commande dont les lignes ne sont pas passées.

Avec la possibilité d'envoyer par mail les lignes rejetées.

A la fin on commit. En utilisant tOracleConnection + tOraclecommit ?
atb est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/03/2011, 10h40   #13
Invité de passage
 
Coco Enrico
Inscription : novembre 2009
Messages : 6
Détails du profil
Informations personnelles :
Nom : Coco Enrico

Informations forums :
Inscription : novembre 2009
Messages : 6
Points : 1
Points : 1
Bonjour,

Citation:
Envoyé par tetsu no tama Voir le message
Si j'ai bien compris le besoin de enricococo40, la transaction doit garantir que l'ensemble : "commande / lignes de commande" est Ok.
Je souhaitais simuler la gestion d'une transaction avec un traitement ligne par ligne.

En code grosso modo ça aurait donné ça:

-- Ouverture d'un curseur
-- Boucle de Lecture du curseur
-- Ouverture d'une transaction SQL

-- Insertion table 1
-- Maj table 2
-- Insertion ou update table 3

-- Gestion des Exceptions
-- Si aucune exception commit
-- Sinon Rollback

-- Fermeture de la transaction
--Retour au début de la boucle

J'ai réussi à trouver la façon de faire fonctionner le traitement en remplaçant mon composant tjava par un composant tjavarow juste après les rejets. Ce composant met à jour une variable d'erreur que je teste ensuite pour faire le commit rollback. Cette variable est remise à jour par le tjavaflex à chaque itération.

Pour ceux que ça intéresse, l'itération est assez couteuse au niveau de la performance. Dans mon cas, je n'ai pas trouvé le moyen de m'en passer.

Le passage par un job/sous job est comme le signalait "tetsu no tama" très pénalisant niveau performance et je suis d'accord avec lui ça fait un peu bidouille...

Merci pour votre aide.
Images attachées
Type de fichier : jpg TalendCommitRollbackOK.jpg (37,4 Ko, 19 affichages)
enricococo40 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h27.


 
 
 
 
Partenaires

Hébergement Web