Writeb permet une optimisation des performances pour une boucle d'écritures d'enregistrements dans une table de la base de données.
Writeb [ classe ]
Elément | Description | Restrictions |
classe | Abréviation d'une table, par défaut la table par défaut. | La table doit avoir été ouverte par un ordre File. |
Call DEBTRANS From GLOCK
adxwrb=10 : # Valeur raisonnable
$TR1
[V]GOK = 1 : Trbegin [SOH] : # Début de transaction
# Boucle sur les deux tables (chacune ayant son buffer)
For nolign=1 to [M]LINNBR
[F:SOP]=[M] : Writeb [SOP] : # Ecriture avec buffer
If [S]fstat<>0
If adxwrb=1 : Call FSTA(“SOP”) From GLOCK : Endif : On connait la ligne erronée
Break : # erreur sur une des lignes
Endif
[F:SOQ]=[M] : Writeb [SOQ] : # Ecriture avec buffer
If [S]fstat<>0
If adxwrb=1 : Call FSTA(“SOP”) From GLOCK : Endif : On connait la ligne erronée
Break : # erreur sur une des lignes
Endif
Next nolign
If [S]fstat<>0 : Goto ROL_TR1 : Endif : # Erreur sur une des lignes
# Assurons-nous que toutes les lignes [SOP] et [SOQ] ont été écrites
If adxwrb>1
Flush [SOP] : If [S]fstat<>0 : Goto ROL_TR1 : Endif
Flush [SOQ] : If [S]fstat<>0 : Goto ROL_TR1 : Endif
Endif
# Ecrivons l’en-tête
[F:SOH]=[M]
Write [SOH] : # pas d’empilement ici, on n’en n’écrit qu’un
If [S]fstat<>0
Call FSTA(“SOH”) From GLOCK : Goto ROL_TR1 : # Erreur sur l’en-tête
Endif
Commit
Return : # Tout est OK
# En cas d’erreur, on recommence si on était en mode groupé pour identifier la ligne erronée
$ROL_TR_1
Rollback
If adxwrb>1 : adxwrb=1 : Goto TR1
GOK=0
Return
Writeb permet de bufferiser les enregistrements avant de les écrire dans la base de données. On utilise cette instruction plutôt que l'instruction Write, dans un traitement de création massive d'enregistrement dans une même table.
Si la variable [S]adxwrb <= 1, l'instruction Writeb fonctionne comme l'instruction Write.
Si la variable [S]adxwrb > 1, l'instruction Writeb bufferise l'enregistrement. Les enregistrements bufferisés sont ensuite écrits dans la base de données au n'ième appel de l'instruction Writeb, lors 'n' est la valeur de la variable système [s]adxwrb.
Writeb sur une table comportant un clob ou un blob se comporte comme un Write; il ne bufferise pas l'enregistrement.
Writeb met à jour la variable fstat pour indiquer comment se sont déroulées les écritures, par contre la ligne en erreur n'est pas identifiée. Une solution permettant d'identifier la ligne en erreur est de positionner [S]adxwrb après le rollback et de retenter la transaction de mise à jour sans bufferisation. Ainsi, lo'erreur se produira sur la ligne en cours d'écriture.
fstat | Code | Ecr. | Explication |
0 | Oui | L'écriture a eu lieu correctement. | |
1 | ERLOCK | Non | Table verrouillée. |
3 | ERDUPCL | Non | Tentative de création d'une clé dupliquée. |
L’instruction Flush provoque l’écriture des lignes qui n’auraient pas été écrites et resteraient dans le buffer. Attention, il est impératif de faire un Flush avant de faire le Commit ! En effet, non seulement le Commit ne “flushe” pas les lignes envoyées par Writeb, mais en plus il provoque une erreur s’il subsiste des lignes non envoyées dans le buffer d’écriture. Il est donc important de faire un Flush lorsqu’on veut s’assurer que les lignes ont été écrites, et en tout état de cause avant le Commit final.
L’instruction Rollback prend bien entendu en compte toutes les écritures, qu’elles soient faites par Writeb ou Write.
L’exemple donné ici correspond à un cas où on réalise des créations en cascade. C’est le cas qui est le plus intéressant du point de vue de l’optimisation. Le code écrit à l’étiquette ROL_TR_1 ne vise pas vraiment à recommencer la transaction dans l’espoir qu’elle réussisse (s’il y avait des clés dupliquées, elles vont rester sauf suppression par un autre utilisateur) ; il vise simplement à relancer la transaction ligne à ligne, afin de savoir identifier la ligne exacte où se produit l’erreur.
La modification de la variable adxwrb provoque une erreur si des lignes sont encore dans des buffers d’écriture. Il est donc impératif de faire les Flush ou un Rollback avant de la modifier.
L’instruction Writeb affectant des buffers dont la taille est plus conséquente que les buffers d’écriture habituels, il n’est pas exclu qu’une erreur « pas assez de mémoire » (31) soit renvoyée au moment de son exécution. Il faudra dans ce cas revoir à la hausse le paramètre sadmem. Ce paramètre règle la mémoire consommée par les processus sadodbc et sadora. Par défaut, sur une version 6.2 standard, il est fixé à 20480. Si besoin, augmenter sa valeur en fonction du nombre de tables dans lesquelles on fait de l’écriture bufferisée, de la taille d’un enregistrement de ces tables, et de la valeur donnée à adxwrb.
Attention !
Ecrire les traitement de telle manière, qu'il n'y ait pas de problème dans l'ordre d'écriture des enregistrements dans la base de données. Si l'ordre d'écriture des enregistrements à de l'importance, ne pas utiliser l'instruction Writeb avec une instruction Update or Write.
Exemple 1 - incorrect
adxwrb=10 : [F:ABC]CLE= "ABC" [F:ABC]NOM=”alphabet”: Writeb [ABC]
Update [F:ABC]CLE=”ABC” With NOM=”alpha plus bête qu’avant” : Writeb [ABC]
Dans cet exemple, on va avoir une erreur sur l’Update, puisque la clé n’est pas encore réellement écrite.
Exemple 2 - incorrect
adxwrb=1+int(rnd(10))
Trbegin [ABC]
For I=1 to 100
Read [F:ABC]CLE
[F:ABC]CLE= "ABC"+num$(I) : Writeb [ABC]
[F:ABC]CLE= "DEF"+num$(I) : Write [ABC]
Next I
Flush [ABC]
Commit
A la fin de la boucle, l’ensemble des lignes “ABC” et “DEF” auront été insérées dans la base, mais ici on ne maîtrise pas l’ordre dans lequel elles sont insérées (les lignes DEF sont insérées au fur et à mesure, les lignes ABC sont insérées par paquets de adxwrb lignes).