Les instructions COMMIT WORK et ROLLBACK WORK sont centrales pour le contrôle des transactions en ABAP. Elles déterminent si les modifications de base de données sont sauvegardées de manière permanente ou annulées.
Concept de base : Logical Unit of Work (LUW)
En ABAP, les modifications de base de données ne sont pas immédiatement sauvegardées de manière permanente. Au lieu de cela, elles sont collectées dans un tampon de transaction jusqu’à ce qu’une décision explicite soit prise :
COMMIT WORK: Toutes les modifications sont sauvegardées de manière permanente dans la base de données.ROLLBACK WORK: Toutes les modifications depuis le dernier COMMIT sont annulées.
Une Logical Unit of Work (LUW) est l’ensemble de toutes les opérations de base de données entre deux points COMMIT. La LUW garantit que soit toutes les modifications sont sauvegardées, soit aucune (atomicité).
COMMIT WORK – Sauvegarder les modifications
Syntaxe
COMMIT WORK [AND WAIT].Fonctionnement
- Toutes les modifications de base de données en tampon sont écrites dans la base de données.
- Tous les modules fonction UPDATE enregistrés sont exécutés.
- Le tampon de transaction est vidé.
- Une nouvelle LUW commence.
Variantes
| Variante | Description |
|---|---|
COMMIT WORK | Commit asynchrone. Le programme continue immédiatement. |
COMMIT WORK AND WAIT | Commit synchrone. Le programme attend que toutes les modifications soient terminées. |
Exemple
DATA: ls_customer TYPE zcustomer.
ls_customer-id = '1001'.ls_customer-name = 'Nouvelle Société SARL'.ls_customer-city = 'Paris'.
" Insérer l'enregistrement (pas encore permanent)INSERT INTO zcustomer VALUES @ls_customer.
IF sy-subrc = 0. " Sauvegarder les modifications de manière permanente COMMIT WORK AND WAIT.
IF sy-subrc = 0. WRITE: / 'Client créé et sauvegardé avec succès.'. ELSE. WRITE: / 'Erreur lors de la sauvegarde.'. ENDIF.ELSE. " En cas d'erreur : Annuler les modifications ROLLBACK WORK. WRITE: / 'Le client n a pas pu être créé.'.ENDIF.ROLLBACK WORK – Annuler les modifications
Syntaxe
ROLLBACK WORK.Fonctionnement
- Toutes les modifications de base de données en tampon sont annulées.
- Tous les modules fonction UPDATE enregistrés ne sont pas exécutés.
- Le tampon de transaction est vidé.
- Une nouvelle LUW commence.
Exemple
DATA: lt_orders TYPE TABLE OF zorder.
" Effectuer plusieurs opérationsINSERT zorder FROM TABLE @lt_orders.
UPDATE zcustomer SET last_order = @sy-datum WHERE id = '1001'.
" Vérification des erreursIF sy-subrc <> 0. " En cas d'erreur : Annuler TOUTES les modifications ROLLBACK WORK. WRITE: / 'Transaction annulée.'. RETURN.ENDIF.
" Tout OK : SauvegarderCOMMIT WORK.Champs système
Après COMMIT WORK :
sy-subrc:0: Commit réussi (avecAND WAIT).- Pour un commit asynchrone sans
AND WAIT,sy-subrcest toujours0.
Après ROLLBACK WORK :
- Aucun champ système pertinent n’est défini.
LUW Base de données vs. LUW SAP
LUW Base de données
La LUW base de données comprend toutes les opérations directes de base de données (INSERT, UPDATE, DELETE, SELECT) entre deux points COMMIT.
" LUW Base de données 1 commence
INSERT zcustomer FROM @ls_customer1.UPDATE zproduct SET price = 100 WHERE id = 'P001'.
COMMIT WORK. " LUW Base de données 1 termine
" LUW Base de données 2 commence
DELETE FROM zlog WHERE created < '20240101'.
COMMIT WORK. " LUW Base de données 2 termineLUW SAP (Logical Unit of Work)
La LUW SAP est un concept étendu qui inclut également les modules fonction UPDATE et la mise à jour. Elle permet de regrouper les modifications de base de données et de ne les exécuter qu’à la fin d’une transaction métier.
" Enregistrer les modifications (pas encore de modification DB)CALL FUNCTION 'Z_UPDATE_CUSTOMER' IN UPDATE TASK EXPORTING customer = ls_customer.
CALL FUNCTION 'Z_UPDATE_ORDER' IN UPDATE TASK EXPORTING order = ls_order.
" Maintenant toutes les fonctions enregistrées sont exécutéesCOMMIT WORK.UPDATE TASK – Mise à jour
Avec IN UPDATE TASK, les modules fonction peuvent être enregistrés pour la mise à jour asynchrone :
Module fonction pour la mise à jour
FUNCTION z_update_customer.*"----------------------------------------------------------------------*" IMPORTING*" VALUE(customer) TYPE zcustomer*"----------------------------------------------------------------------
" Ce code est exécuté lors du COMMIT WORK MODIFY zcustomer FROM customer.
ENDFUNCTION.Appel dans le programme principal
DATA: ls_customer TYPE zcustomer.
ls_customer-id = '1001'.ls_customer-name = 'Société modifiée'.
" Enregistrer la fonction de mise à jourCALL FUNCTION 'Z_UPDATE_CUSTOMER' IN UPDATE TASK EXPORTING customer = ls_customer.
" Logique supplémentaire...
" À la fin : Exécuter toutes les mises à jourCOMMIT WORK AND WAIT.Avantages de la mise à jour
- Regroupement : Toutes les modifications sont exécutées ensemble.
- Gestion des erreurs : En cas d’erreur, toute la LUW est annulée.
- Performance : L’exécution asynchrone décharge le dialogue.
COMMIT implicite
Un COMMIT WORK est exécuté automatiquement lors de :
- Fin d’une étape de dialogue (action utilisateur comme ENTER, touche F)
- Appel d’une transaction (
CALL TRANSACTION,LEAVE TO TRANSACTION) - Appel d’un module fonction RFC
- Envoi d’un message de type
A(Abandon) ouX(Exit)
Attention : Cela peut provoquer des commits non intentionnels !
" ATTENTION : Commit implicite !INSERT zcustomer FROM @ls_customer.
" Cet appel exécute un COMMIT impliciteCALL TRANSACTION 'VA01'.
" La modification INSERT est maintenant déjà commitée !" Un ROLLBACK WORK ici n'aurait plus d'effet.ROLLBACK implicite
Un ROLLBACK WORK est exécuté automatiquement lors de :
- Erreur d’exécution (Dump)
- Message de type
A(dans certains contextes) - Abandon de programme
Bonnes pratiques pour les transactions
1. Gestion des erreurs avec ROLLBACK
DATA: lv_error TYPE abap_bool VALUE abap_false.
" Opération 1INSERT zcustomer FROM @ls_customer.IF sy-subrc <> 0. lv_error = abap_true.ENDIF.
" Opération 2IF lv_error = abap_false. UPDATE zorder SET customer_id = @ls_customer-id WHERE order_id = @lv_order_id. IF sy-subrc <> 0. lv_error = abap_true. ENDIF.ENDIF.
" DécisionIF lv_error = abap_false. COMMIT WORK AND WAIT. WRITE: / 'Transaction réussie.'.ELSE. ROLLBACK WORK. WRITE: / 'Transaction échouée.'.ENDIF.2. TRY-CATCH avec ROLLBACK
TRY. INSERT zcustomer FROM @ls_customer. IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_failed_insert. ENDIF.
UPDATE zorder SET status = 'PROCESSED" WHERE customer_id = @ls_customer-id.
COMMIT WORK AND WAIT.
CATCH cx_failed_insert. ROLLBACK WORK. WRITE: / 'Erreur lors de l insertion.'.
CATCH cx_root INTO DATA(lx_error). ROLLBACK WORK. WRITE: / 'Erreur inattendue:', lx_error->get_text( ).ENDTRY.3. Verrous avant modifications
" Demander le verrouCALL FUNCTION 'ENQUEUE_EZCUSTOMER" EXPORTING id = ls_customer-id EXCEPTIONS foreign_lock = 1 OTHERS = 2.
IF sy-subrc <> 0. WRITE: / 'L enregistrement est verrouillé.'. RETURN.ENDIF.
" Effectuer les modificationsUPDATE zcustomer FROM @ls_customer.
" CommitCOMMIT WORK AND WAIT.
" Libérer le verrouCALL FUNCTION 'DEQUEUE_EZCUSTOMER" EXPORTING id = ls_customer-id.COMMIT WORK vs. COMMIT WORK AND WAIT
| Aspect | COMMIT WORK | COMMIT WORK AND WAIT |
|---|---|---|
| Exécution | Asynchrone | Synchrone |
| Temps d’attente | Aucun | Attend la fin |
| sy-subrc | Toujours 0 | Indique succès/échec |
| Utilisation | Arrière-plan, si résultat non critique | Dialogue, si résultat doit être vérifié |
" Asynchrone : Plus rapide, mais pas de feedbackCOMMIT WORK.
" Synchrone : Plus lent, mais avec vérification d'erreurCOMMIT WORK AND WAIT.IF sy-subrc <> 0. " Gestion des erreursENDIF.Erreurs fréquentes
1. COMMIT oublié
" FAUX : Pas de COMMITINSERT zcustomer FROM @ls_customer." La modification est perdue à la fin du programme !
" CORRECT :INSERT zcustomer FROM @ls_customer.COMMIT WORK.2. COMMIT dans une boucle
" MAUVAIS : COMMIT à chaque itérationLOOP AT lt_customers INTO DATA(ls_cust). INSERT zcustomer FROM @ls_cust. COMMIT WORK. " Très inefficace !ENDLOOP.
" MIEUX : Un seul COMMIT à la finINSERT zcustomer FROM TABLE @lt_customers.COMMIT WORK.3. COMMIT implicite ignoré
INSERT zcustomer FROM @ls_customer.
" ATTENTION : RFC provoque un COMMIT implicite !CALL FUNCTION 'Z_REMOTE_FUNCTION' DESTINATION 'RFC_DEST'.
" ROLLBACK ici est sans effet - les données sont déjà commitéesROLLBACK WORK.Résumé
| Instruction | Effet |
|---|---|
COMMIT WORK | Sauvegarde toutes les modifications de manière asynchrone |
COMMIT WORK AND WAIT | Sauvegarde toutes les modifications de manière synchrone (avec feedback) |
ROLLBACK WORK | Annule toutes les modifications depuis le dernier COMMIT |
Notes importantes / Bonnes pratiques
- Exécutez
COMMIT WORKuniquement aux limites logiques de transaction, pas après chaque opération individuelle. - Utilisez
COMMIT WORK AND WAITlorsque vous devez vérifier le résultat. - Implémentez une gestion des erreurs cohérente avec
ROLLBACK WORK. - Tenez compte des COMMITs implicites lors des appels de transaction et RFC.
- Utilisez les verrous SAP pour éviter les conflits de données lors des accès parallèles.
- Testez les transactions critiques d’abord avec
ROLLBACK WORKà la fin. - Dans les modules fonction de mise à jour (
IN UPDATE TASK), n’utilisez jamaisCOMMIT WORKouROLLBACK WORK. - Utilisez
INSERT,UPDATE,DELETEpour les modifications réelles de base de données.