Valider une transaction

      Après son démarrage, une transaction peut s'achever sur une annulation ou une validation. Nous allons ici nous intéresser aux validations.
      Démonstration avec PostgreSQL 12 beta, psql est configuré par défaut :

select version(); version ---------------------------------------------------------------------------------------------------------------------- PostgreSQL 12beta1 (Debian 12~beta1-1.pgdg+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-7) 8.3.0, 64-bit create table geants(idge integer, nmge character varying(32)); CREATE TABLE -- session A insert into geants values(1, 'OUMPFOR'); INSERT 0 1 -- session B select * from geants; idge | nmge ------+--------- 1 | OUMPFOR (1 ligne)

      PostgreSQL travaille en autocommit par défaut, chaque instruction constitue une transaction automatiquement et implicitement validée.
      Nous allons à présent démarrer explicitement la transaction dans la session A manipulant les données :

select version(); version ---------------------------------------------------------------------------------------------------------------------- PostgreSQL 12beta1 (Debian 12~beta1-1.pgdg+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-7) 8.3.0, 64-bit -- session A start transaction; START TRANSACTION insert into geants values(2, 'BALOS'); INSERT 0 1 -- session B select * from geants; idge | nmge ------+--------- 1 | OUMPFOR (1 ligne) -- session A commit; COMMIT -- session B select * from geants; idge | nmge ------+--------- 1 | OUMPFOR 2 | BALOS (2 lignes)

      Démarrage explicite, validation explicite. Le niveau d'isolation par défaut de PostgreSQL est le READ COMMITTED. Les données modifiées ne sont visibles par d'autres transactions qu'après la validation de la transaction par COMMIT.
      A présent, une démonstration similaire avec Oracle Database 19c :

Connected to: Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production Version 19.3.0.0.0 create table geants(idge integer, nmge character varying(32)); Table created. -- session A insert into geants values(1, 'OUMPFOR'); 1 row created. -- session B select * from geants; no rows selected -- session A commit; Commit complete. -- session B select * from geants; IDGE NMGE ---------- -------------------------------- 1 OUMPFOR

      Avec Oracle Database, les transactions sont démarrées implicitement avec la première instruction DML (insert, update, delete, merge) et il n'y a pas d'autocommit par défaut.
      Le niveau d'isolation par défaut est en revanche comme avec PostgreSQL le READ COMMITTED. Les données modifiées ne sont visibles par d'autres transactions qu'après la validation de la transaction par COMMIT.
      Particularité (malheureuse...) d'Oracle Database, toute instruction DDL (create table etc.) ou DCL (grant etc.) valide implicitement une transaction (le moteur réalise en fait un commit avant et après l'instuction)
      Démonstration :

Connected to: Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production Version 19.3.0.0.0 -- session A insert into geants values(2, 'BALOS'); 1 row created. create index geants_i1 on geants(nmge); Index created. -- session B select * from geants; IDGE NMGE ---------- -------------------------------- 1 OUMPFOR 2 BALOS

      La création de l'index a ici implicitement validé la transaction dans notre session A. Au passage d'Oracle Database à PostgreSQL, si vous désactivez l'autocommit (par exemple en positionnant \set AUTOCOMMIT off avec psql), la difficulté peut venir de l'habitude de compter sur ce COMMIT implicite. Il ne faut pas oublier de faire "COMMIT" !
      PostgreSQL 12, en beta au 22/05/2019, permet d'enchaîner automatiquement une nouvelle transaction après validation de la précédente, avec le même niveau d'isolation, grâce aux mots clés "AND CHAIN". Par défaut, une nouvelle transaction n'est pas enchaînée ("COMMIT" est équivalent à "COMMIT AND NO CHAIN").
      Démonstration :

select version(); version ---------------------------------------------------------------------------------------------------------------------- PostgreSQL 12beta1 (Debian 12~beta1-1.pgdg+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-7) 8.3.0, 64-bit start transaction isolation level serializable; START TRANSACTION insert into geants values(3, 'CARIA'); INSERT 0 1 select * from current_timestamp; current_timestamp ------------------------------- 2019-05-22 11:08:47.521655+02 commit and chain; COMMIT select * from current_timestamp; current_timestamp ------------------------------- 2019-05-22 11:09:20.899389+02 SHOW transaction_isolation; transaction_isolation ----------------------- serializable (1 ligne)

      Cette fonctionnalité est bienvenue : PostgreSQL continue d'améliorer sa gestion transactionnelle dans le respect du standard SQL.

Mise à jour : 22/05/2019