Transaction bonne pratique

Bonjour à tous.

J’ai remarqué des utilisations différentes au niveaux des transactions. Et j’aimerai savoir quelle est la meilleure méthode entre la méthode 1 et méthode 2 :

méthode 1 :
1 - Mettre la table en lecture/ecriture
2 - Debuter une transaction
3 - TRAITEMENT
4 - Sauvegarder enregistrement (ou annuler enregistrement)
5 - Valider transaction (ou annuler transaction)
6 - Remettre la table en lecture seule

<code 4D>
READ WRITE([maBelleTable])
START TRANSACTION
CREATE RECORD([maBelleTable])
[maBelleTable]monChamp:=maValeur
SAVE RECORD([maBelleTable])
VALIDATE TRANSACTION
READ ONLY([maBelleTable])
</code 4D>

méthode 2 :
1 - Mettre la table en lecture seule
2 - Debuter une transaction
3 - TRAITEMENT
4 - Mettre la table en lecture/ecriture
5 - Sauvegarder enregistrement (ou annuler enregistrement)
6 - Valider transaction (ou annuler transaction)
7 - Remettre la table en lecture seule

<code 4D>
CREATE RECORD([maBelleTable])
READ ONLY([maBelleTable])
START TRANSACTION
[maBelleTable]monChamp:=maValeur
READ WRITE([maBelleTable])
SAVE RECORD([maBelleTable])
VALIDATE TRANSACTION
READ ONLY([maBelleTable])
</code 4D>

Je pense que dans le premier cas on perd l’intérêt réel des transaction en bloquant l’écriture pour les autres utilisateurs.
Je voudrais vraiment faire le truc le plus propre possible, donc j’aimerais vos avis d’expert, vos suggestions etc :slight_smile:
D’avance merci à tout le monde

Vous êtes en phase de creation d’enregistrement la notion de lecture
écriture ou lecture seulement n’a pas lieu d’être ici…

En plus si vous
<http://doc.4d.com/4Dv16R5/4D/16-R5/LECTURE-ECRITURE.301-3481607.fr.htm

relisez la doc> il est clairement spécifié que :

: Doc 4D: LECTURE ECRITURE

Note : Cette commande n’est pas rétroactive. Les privilèges de
lecture/écriture pour un enregistrement sont définis par ceux de la
table au moment où l’enregistrement est chargé. Pour qu’un
enregistrement soit chargé en mode lecture/écriture alors que la
table est en mode lecture seulement, vous devez placer la table en
mode lecture/écriture avant que l’enregistrement soit chargé.

http://doc.4d.com/4Dv16R5/4D/16-R5/Verrouillage-d-enregistrements.300-3481609.fr.htmlVerrouillage d’enregistrements>

Effectivement j’ai mis creation, mais ma question était plutôt pour la modification d’un enregistrement. Erreur d’inattention…
Donc je parler plutot de la commande LOAD RECORD :

Methode 1 :
READ WRITE([maBelleTable])
LOAD RECORD([maBelleTable])
START TRANSACTION
[maBelleTable]monChamp:=maValeur
SAVE RECORD([maBelleTable])
VALIDATE TRANSACTION
READ ONLY([maBelleTable])

Méthode 2 :
READ ONLY([maBelleTable])
LOAD RECORD([maBelleTable])
START TRANSACTION
[maBelleTable]monChamp:=maValeur
READ WRITE([maBelleTable])
SAVE RECORD([maBelleTable])
VALIDATE TRANSACTION
READ ONLY([maBelleTable])

Même avec une modification, la méthode 2 me parait suspecte ton enregistrement est charger en mode lecture seul et ce n’est pas ton passage en lecture écriture juste avant ton stocker enregistrement qui va changer quelque chose…

: Bastien ROUSSEL

Je pense que dans le premier cas on perd l’intérêt réel des
transaction en bloquant l’écriture pour les autres utilisateurs.
Un nouvel enregistrement dans 4D est à peu près comme un “sans titre” word ou excel, les autres postes ne savent pas qu’il existe. Le serveur gère des verrous sur les enregistrements existant dans le 4dd, c’est déjà pas mal.

En dehors de ça, je n’aime pas du tout la seconde écriture : la transaction doit encadrer ce qu’elle protège. Ce create record hors de la transaction est comme un cheveux sur la soupe.

Il y a un autre problème dans ton exemple: a quoi te sert réellement ta transaction ? si c’est uniquement un seul enregistrement qui est modifié, la transaction ne sert à rien…

La transaction permet la validation ou l’annulation en lot, typiquement l’exemple des lignes de facture qui n’ont pas d’existence sans leur facture.

En plus en fonction de ton code la position de ton démarrage de transaction peut être différent; il peut être concevable de démarrer une transaction après un charger enregistrement et de la valider avant un stockage d’enregistrement justement si elle porte sur des enregistrements différents. On valide(ou pas) la creation/modification des lignes de facture, mais on valide la facture à tous les coups par exemple pour stocker une info sur la fiche de la facture, etc…

: Manuel PIQUET

Il y a un autre problème dans ton exemple: a quoi te sert réellement
ta transaction ? si c’est uniquement un seul enregistrement qui est
modifié, la transaction ne sert à rien…

Une transaction peut servir pour prévenir un crash

Voici une méthode pour charger un enregistrement :

http://forums.4d.com/4DBB_Main/x_User/3906/files/23166464.zip

<code 4D>
// Method 4DREC_Load_Record tente de charger l’enregistrement de la table passée en paramètre
//
//
// #SYNTAX: $L_Erreur:=4DREC_Load_Record(->Table;->message)
// #PARAMETERS:
// None
// $0 Long : error code. 1 = OK
// $1 Pointeur : la table de l’enregistrement à tester
// $2 Pointer : message

// #DATE CREATION: 26/10/2011 #AUTHOR: Bertrand SOUBEYRAND info@soubeyrand-4d-developer.eu
// #DATE MODIFICATION: 01/09/2013
// #NOTE: Locked retourne FAUX même quand l’enregistrement a été supprimé

// #HEADER VERSION: 2

C_LONGINT($0)

C_POINTER($1;$P_Table)
$P_Table:=$1

C_POINTER($2;$P_Message)
$P_Message:=$2

LOAD RECORD($P_Table->)

C_BOOLEAN($B_Locked)
$B_Locked:=Locked($P_Table->)

C_TEXT($T_User;$T_UserSession;$T_Process)
C_LONGINT($L_Process)
LOCKED BY($P_Table->;$L_Process;$T_User;$T_UserSession;$T_Process)

C_LONGINT($L_MyError)
Case of
: (Read only state($P_Table->))
$L_MyError:=-3
: ($B_Locked)
$L_MyError:=-1
: ($L_Process=-1) // Contournement BUG 4D
$L_MyError:=-2
Else
$L_MyError:=1
End case

C_TEXT($T_Message)
Case of
: ($L_MyError=-1)
$T_Message:="L’enregistrement de “+Table name($P_Table)+” est verrouillé.\rUtilisateur : “+$T_User+”\rSession : “+$T_UserSession+”\rProcess : "+$T_Process
: ($L_MyError=-2)
$T_Message:=“L’enregistrement de “+Table name($P_Table)+” n’existe plus”
: ($L_MyError=-3)
$T_Message:=“La “+Table name($P_Table)+” est en lecture seule”
Else
$T_Message:=“OK”
End case

$0:=$L_MyError
$P_Message->:=$T_Message
</code 4D>

: Bertrand SOUBEYRAND

Une transaction peut servir pour prévenir un crash
OK, mais à ce compte là, vous faites tout sous transaction… :roll:

Non mais la c’etait un exemple tres tres basique, je n’utiliserai jamais dans un cas comme celui-ci.

Merci de la réponse :slight_smile:

Merci Bertrand :slight_smile: