Recherche sur le blog

mardi 9 juillet 2013

[Système] Windows Installer Coordinator boucle

Lorsque vous tentez d’installer certaines applications sur Windows Server 2008 R2 qui sont des packages MSI, il peut arriver qu’une fenêtre “Windows Installer Coordinator” s’ouvre et n’aboutisse à aucun résultat. Votre installation est alors suspendue, il ne vous reste plus qu’à annuler. Cela arrive notamment avec des logiciels comme IBM Client Access v7.1, qui fait plusieurs fois appel au service de Windows Installer.

01-apr-11-17-02-55

En général, ce problème survient lorsqu’on essaie de lancer l’installation depuis une session Remote Desktop (RDS), aussi connu sous le nom de “Terminal Server”. Il y a cependant un moyen de le contourner

Gestion des stratégies de groupes

Sur l’ordinateur/serveur en question, ou dans l’Active Directory – en fonction de votre infrastructure donc –, vous devez accéder à la console de gestion des stratégies de groupes. Vous pouvez trouver celle-ci dans les “Outils d’administration”, ou en utilisant la commande “gpedit.msc”. N’oubliez pas qu’il est nécessaire de posséder les privilèges d’administrateur pour effectuer ces manipulations.

Développez l’arborescence suivante : Configuration de l’ordinateur, Modèles d’administration, Composants Windows, Services Bureau à distance, Hôte de la session Bureau à distance, Compatibilité des applications.

gpedit

A droite, double-cliquez sur “Désactiver la compatibilité des services Bureau à distance” et choisissez “Activer”, puis confirmez par OK. Ensuite, ouvrez le menu démarrer, cliquez sur “Exécuter” (Windows+R) puis saisissez la commande “cmd”. Saisissez la commande “gpupdate /force” et patientez un moment.

Autre méthode : modifier une clé de registre

Accédez à l’éditeur de registre (regedit) puis développez l’arborescence jusqu’à la clé : HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services\TSAppSrv\TSMSI. Vous y trouverez une valeur de type “DWORD” appelée “Enable”. Il faut définir la valeur de celle-ci à 0. Ensuite, il sera peut-être préférable de redémarrer l’ordinateur pour que les modifications soient prises en compte.

Sources

Gearbytes
KB2655192

Lukas Beeler’s IT Blog

mercredi 3 juillet 2013

[SQL] Réaliser des “upserts” sur DB2/400

Beaucoup de SGBD proposent des requêtes plutôt simples pour réaliser ce qu’on appelle couramment des “upserts” (ou encore “insert-or-update). Cela permet donc d’effectuer une mise à jour si l’insertion échoue. Dans DB2/400, il faut utiliser une requête “MERGE INTO”. La documentation d’IBM, en plus de détailler chaque clause, propose également des exemples concrets. Le principe est simple : la requête se base sur une condition de recherche. Il faut alors prévoir le cas où la recherche a abouti et le cas contraire.

Syntaxe

5mergesyntax

Exemple

4mergeinto

Comme on le voit dans l’exemple ci-dessus, la condition de recherche peut être simplement un ensemble de valeurs, qui constituent alors une table. Une jointure est alors effectuée sur la table dans laquelle on veut faire les mises à jour (p.x = s.x). Notez que l’on peut aussi utiliser directement une table (ex : USING matable) ou bien une requête de sélection.

[Java] Exécuter un lot de requêtes SQL

Grâce à JDBC, il vous est possible de gagner en performances en exécutant un lot de requêtes – aussi appelé “batch” – pour effectuer des insertions, des mises à jour ou même des suppressions. Par défaut, toutes les requêtes seront considérées chacune comme étant des transactions, car l’auto-commit est activé lors de l’utilisation de l’objet Connection. Ce comportement pourra être modifié en utilisant la fonction “myConnection.setAutoCommit(false)”.

Pour rappel, les SGBD prévoient des “niveaux d’isolation” pour l’exécution de vos transactions. Par exemple, le niveau le plus strict – Serializable – ne permet aucune lecture impropre (T2 lit une donnée mise à jour par T1 alors que cette dernière a été annulée – la valeur lue n’est donc pas valide), aucune lecture fantôme (risque d’obtenir des données en plus ou en moins mais non-validées) ni non-reproductible (lecture d’une valeur par T2 avant et après mise à jour par T1 ; différente aux deux exécutions). Le tableau ci-dessus indique les phénomènes qui peuvent se produire dans chaque niveau.

isolationsgbd

Les différents niveaux sont définis en tant que constantes dans la classe Connection.

Préparer la requête

En Java, pour exécuter une requête, nous pouvons utiliser les Statement, mais cela impose de devoir construire soi-même la chaine. Pour éviter les soucis classiques d’injection SQL, on peut se diriger vers les PreparedStatement. La requête est définie une seule fois, les paramètres sont indiqués dans l’ordre et par des “?”.

0insertquery

Pour obtenir un objet “PreparedStatement”, il faut utiliser la fonction “prepareStatement” de l’objet Connection que vous avez déclaré. En paramètre, nous passons la requête d’insertion définie ci-dessus.

1preparestatement

Dans une boucle, nous allons effectuer un traitement pour insérer les différentes valeurs. Nous allons ajouter la requête sans pour autant l’exécuter directement. C’est comme si l’on créait un script SQL contenant plusieurs requêtes séparées par des point-virgules.

2psiset

Exécution

Grâce à une variable de type entier servant de compteur, nous allons exécuter chaque lot toutes les 100 requêtes. Vous pouvez essayer de plus grandes valeurs comme 1000 ou 10 000 mais il se pourrait bien qu’en fonction du SGBD, vous soyez contraints de diminuer celle-ci.

3executeBatch

A chaque fois que l’on utilise “executeBatch”, un tableau d’entiers est retourné. Il contient le résultat pour chaque ligne de commande du lot. La valeur est soit supérieure ou égale à 0 et correspond alors au nombre de lignes affectées par la mise à jour, soit égale à l’une des deux constantes suivantes de la classe Statement : EXECUTE_FAILED (échec de la commande, pas d’exception) ou SUCCESS_NO_INFO (l’exécution a réussi mais aucune information n’est disponible quant au nombre de lignes affectées).

Remarque : il convient d’utiliser une dernière fois “executeBatch” juste après la boucle, car il est possible que la condition contenue dans l’instruction “if…” n’ait pas été remplie.

Le traitement de l’exception “BatchUpdateException” est vivement recommandé ! Celle-ci propose une fonction “getUpdateCounts()” qui vous indiquera combien de lignes ont été mises à jour, pratique si vous souhaitez l’indiquer à l’utilisateur. Ensuite, il sera possible d’annuler la transaction grâce à la fonction “rollback” de l’objet Connection.