> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-fbfa8bee.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Page décrivant la prise en charge des transactions (ACID) dans ClickHouse

# Prise en charge des transactions (ACID)

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            Non pris en charge par ClickHouse Cloud
        </div>;
};

export const ExperimentalBadge = () => {
  return <div className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Fonctionnalité expérimentale. <u><a href="/docs/beta-and-experimental-features#experimental-features">En savoir plus.</a></u>
        </div>;
};

<div id="case-1-insert-into-one-partition-of-one-table-of-the-mergetree-family">
  ## Cas 1 : INSERT dans une partition d’une table de la famille MergeTree\*
</div>

Cette opération est transactionnelle (ACID) si les lignes insérées sont compactées et insérées sous la forme d’un seul bloc (voir les remarques) :

* Atomicité : un INSERT réussit ou est rejeté dans son ensemble : si une confirmation est envoyée au client, toutes les lignes ont été insérées ; si une erreur est envoyée au client, aucune ligne n’a été insérée.
* Cohérence : si aucune contrainte de table n’est violée, toutes les lignes d’un INSERT sont insérées et l’INSERT réussit ; si des contraintes sont violées, aucune ligne n’est insérée.
* Isolation : les clients concurrents observent un instantané cohérent de la table — soit l’état de la table tel qu’il était avant la tentative d’INSERT, soit l’état après la réussite de l’INSERT ; aucun état partiel n’est visible. Les clients à l’intérieur d’une autre transaction bénéficient de l’[isolation par instantané](https://en.wikipedia.org/wiki/Snapshot_isolation), tandis que les clients en dehors d’une transaction ont un niveau d’isolation [lecture non validée](https://en.wikipedia.org/wiki/Isolation_\(database_systems\)#Read_uncommitted).
* Durabilité : un INSERT réussi est écrit dans le système de fichiers avant qu’une réponse ne soit renvoyée au client, sur une seule réplique ou sur plusieurs répliques (contrôlé par le paramètre `insert_quorum`), et ClickHouse peut demander à l’OS de synchroniser les données du système de fichiers sur le support de stockage (contrôlé par le paramètre `fsync_after_insert`).
* Un INSERT dans plusieurs tables avec une seule instruction est possible si des vues matérialisées sont impliquées (l’INSERT du client vise une table à laquelle des vues matérialisées sont associées).

<div id="case-2-insert-into-multiple-partitions-of-one-table-of-the-mergetree-family">
  ## Cas 2 : INSERT dans plusieurs partitions d’une table de la famille MergeTree\*
</div>

Identique au cas 1 ci-dessus, avec cette précision :

* Si la table comporte de nombreuses partitions et que l’INSERT en couvre plusieurs, alors l’insertion dans chaque partition constitue à elle seule une transaction

<div id="case-3-insert-into-one-distributed-table-of-the-mergetree-family">
  ## Cas 3 : INSERT dans une table distribuée de la famille MergeTree\*
</div>

Identique au cas 1 ci-dessus, avec ce détail :

* l'INSERT dans une table Distributed n'est pas transactionnel dans son ensemble, tandis que l'insertion dans chaque segment l'est

<div id="case-4-using-a-buffer-table">
  ## Cas 4 : Utiliser une table Buffer
</div>

* les insertions dans les tables Buffer ne sont ni atomiques, ni isolées, ni cohérentes, ni durables

<div id="case-5-using-async_insert">
  ## Cas 5 : utilisation de async\_insert
</div>

Identique au cas 1 ci-dessus, avec ce détail :

* l'atomicité est garantie même si `async_insert` est activé et que `wait_for_async_insert` est défini sur 1 (par défaut), mais si `wait_for_async_insert` est défini sur 0, alors l'atomicité n'est pas garantie.

<div id="notes">
  ## Remarques
</div>

* les lignes insérées depuis le client dans un certain format de données sont regroupées dans un seul bloc lorsque :
  * le format d’insertion est basé sur les lignes (comme CSV, TSV, Values, JSONEachRow, etc.) et que les données contiennent moins de `max_insert_block_size` lignes (\~1 000 000 par défaut) ou moins de `min_chunk_bytes_for_parallel_parsing` octets (10 Mo par défaut) si le parsing parallèle est utilisé (activé par défaut)
  * le format d’insertion est basé sur les colonnes (comme Native, Parquet, ORC, etc.) et que les données ne contiennent qu’un seul bloc de données
* la taille du bloc inséré peut généralement dépendre de nombreux paramètres (par exemple : `max_block_size`, `max_insert_block_size`, `min_insert_block_size_rows`, `min_insert_block_size_bytes`, `preferred_block_size_bytes`, etc.)
* si le client n’a pas reçu de réponse du serveur, il ne sait pas si la transaction a abouti et peut répéter la transaction en s’appuyant sur les garanties d’insertion exactly-once
* ClickHouse utilise en interne [MVCC](https://en.wikipedia.org/wiki/Multiversion_concurrency_control) avec [isolation par instantané](https://en.wikipedia.org/wiki/Snapshot_isolation) pour les transactions concurrentes
* toutes les propriétés ACID restent valides même en cas d’arrêt forcé ou de crash du serveur
* il faut activer soit `insert_quorum` sur différentes AZ, soit `fsync` afin de garantir la durabilité des insertions dans une configuration typique
* la « cohérence » au sens d’ACID ne couvre pas la sémantique des systèmes distribués, voir [https://jepsen.io/consistency](https://jepsen.io/consistency) ; cet aspect est contrôlé par d’autres paramètres (`select_sequential_consistency`)
* cette explication ne couvre pas la nouvelle fonctionnalité de transactions, qui permet d’avoir des transactions complètes sur plusieurs tables, des vues matérialisées, pour plusieurs SELECT, etc. (voir la section suivante sur Transactions, Commit, and Rollback)

<div id="transactions-commit-and-rollback">
  ## Transactions, commit et rollback
</div>

Outre les fonctionnalités décrites au début de ce document, ClickHouse prend en charge, à titre expérimental, les transactions, les commits et les rollbacks.

<div id="requirements">
  ### Prérequis
</div>

* Déployez ClickHouse Keeper ou ZooKeeper pour suivre les transactions
* DB atomic uniquement (par défaut)
* Uniquement le moteur de table MergeTree non répliqué
* Activez la prise en charge expérimentale des transactions en ajoutant ce paramètre dans `config.d/transactions.xml` :
  ```xml theme={null}
  <clickhouse>
    <allow_experimental_transactions>1</allow_experimental_transactions>
  </clickhouse>
  ```

<div id="notes-1">
  ### Remarques
</div>

* Il s’agit d’une fonctionnalité expérimentale et des modifications sont à prévoir.
* Si une exception se produit pendant une transaction, vous ne pouvez pas valider la transaction.  Cela inclut toutes les exceptions, y compris les exceptions `UNKNOWN_FUNCTION` causées par des fautes de frappe.
* Les transactions imbriquées ne sont pas prises en charge ; terminez la transaction en cours et démarrez-en une nouvelle

<div id="configuration">
  ### Configuration
</div>

Ces exemples s'appuient sur un ClickHouse server mono-nœud avec ClickHouse Keeper activé.

<div id="enable-experimental-transaction-support">
  #### Activer la prise en charge expérimentale des transactions
</div>

```xml title=/etc/clickhouse-server/config.d/transactions.xml theme={null}
<clickhouse>
    <allow_experimental_transactions>1</allow_experimental_transactions>
</clickhouse>
```

<div id="basic-configuration-for-a-single-clickhouse-server-node-with-clickhouse-keeper-enabled">
  #### Configuration de base pour un seul nœud ClickHouse server avec ClickHouse Keeper activé
</div>

<Note>
  Consultez la documentation sur le [déploiement](/fr/guides/oss/deployment-and-scaling/terminology) pour plus de détails sur le déploiement de ClickHouse server et sur un quorum adéquat de nœuds ClickHouse Keeper. La configuration présentée ici est fournie à titre expérimental.
</Note>

```xml title=/etc/clickhouse-server/config.d/config.xml theme={null}
<clickhouse replace="true">
    <logger>
        <level>debug</level>
        <log>/var/log/clickhouse-server/clickhouse-server.log</log>
        <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
        <size>1000M</size>
        <count>3</count>
    </logger>
    <display_name>node 1</display_name>
    <listen_host>0.0.0.0</listen_host>
    <http_port>8123</http_port>
    <tcp_port>9000</tcp_port>
    <zookeeper>
        <node>
            <host>clickhouse-01</host>
            <port>9181</port>
        </node>
    </zookeeper>
    <keeper_server>
        <tcp_port>9181</tcp_port>
        <server_id>1</server_id>
        <log_storage_path>/var/lib/clickhouse/coordination/log</log_storage_path>
        <snapshot_storage_path>/var/lib/clickhouse/coordination/snapshots</snapshot_storage_path>
        <coordination_settings>
            <operation_timeout_ms>10000</operation_timeout_ms>
            <session_timeout_ms>30000</session_timeout_ms>
            <raft_logs_level>information</raft_logs_level>
        </coordination_settings>
        <raft_configuration>
            <server>
                <id>1</id>
                <hostname>clickhouse-keeper-01</hostname>
                <port>9234</port>
            </server>
        </raft_configuration>
    </keeper_server>
</clickhouse>
```

<div id="example">
  ### Exemple
</div>

<div id="verify-that-experimental-transactions-are-enabled">
  #### Vérifiez que les transactions expérimentales sont activées
</div>

Exécutez un `BEGIN TRANSACTION` ou un `START TRANSACTION`, puis un `ROLLBACK`, afin de vérifier que les transactions expérimentales sont activées et que ClickHouse Keeper l’est également, car il sert à suivre les transactions.

```sql theme={null}
BEGIN TRANSACTION
```

```response theme={null}
Ok.
```

<Tip>
  Si l’erreur suivante s’affiche, vérifiez votre fichier de configuration pour vous assurer que `allow_experimental_transactions` est défini sur `1` (ou sur toute autre valeur que `0` ou `false`).

  ```response theme={null}
  Code: 48. DB::Exception: Received from localhost:9000.
  DB::Exception: Transactions are not supported.
  (NOT_IMPLEMENTED)
  ```

  Vous pouvez également vérifier ClickHouse Keeper en exécutant :

  ```bash theme={null}
  echo ruok | nc localhost 9181
  ```

  ClickHouse Keeper doit répondre par `imok`.
</Tip>

```sql theme={null}
ROLLBACK
```

```response theme={null}
Ok.
```

<div id="create-a-table-for-testing">
  #### Créer une table de test
</div>

<Tip>
  La création de tables n'est pas transactionnelle. Exécutez cette requête DDL en dehors de toute transaction.
</Tip>

```sql theme={null}
CREATE TABLE mergetree_table
(
    `n` Int64
)
ENGINE = MergeTree
ORDER BY n
```

```response theme={null}
Ok.
```

<div id="begin-a-transaction-and-insert-a-row">
  #### Démarrer une transaction et insérer une ligne
</div>

```sql theme={null}
BEGIN TRANSACTION
```

```response theme={null}
Ok.
```

```sql theme={null}
INSERT INTO mergetree_table FORMAT Values (10)
```

```response theme={null}
Ok.
```

```sql theme={null}
SELECT *
FROM mergetree_table
```

```response theme={null}
┌──n─┐
│ 10 │
└────┘
```

<Note>
  Vous pouvez interroger la table dans une transaction et constater que la ligne a été insérée même si elle n’a pas encore été validée.
</Note>

<div id="rollback-the-transaction-and-query-the-table-again">
  #### Annulez la transaction, puis interrogez de nouveau la table
</div>

Vérifiez que la transaction a bien été annulée :

```sql theme={null}
ROLLBACK
```

```response theme={null}
Ok.
```

```sql theme={null}
SELECT *
FROM mergetree_table
```

```response theme={null}
Ok.

0 rows in set. Elapsed: 0.002 sec.
```

<div id="complete-a-transaction-and-query-the-table-again">
  #### Finaliser une transaction et interroger à nouveau la table
</div>

```sql theme={null}
BEGIN TRANSACTION
```

```response theme={null}
Ok.
```

```sql theme={null}
INSERT INTO mergetree_table FORMAT Values (42)
```

```response theme={null}
Ok.
```

```sql theme={null}
COMMIT
```

```response theme={null}
Ok. Elapsed: 0.002 sec.
```

```sql theme={null}
SELECT *
FROM mergetree_table
```

```response theme={null}
┌──n─┐
│ 42 │
└────┘
```

<div id="transactions-introspection">
  ### Introspection des transactions
</div>

Vous pouvez inspecter les transactions en interrogeant la table `system.transactions`, mais notez que vous ne pouvez pas interroger cette
table depuis une session déjà engagée dans une transaction. Ouvrez une deuxième session `clickhouse client` pour interroger cette table.

```sql theme={null}
SELECT *
FROM system.transactions
FORMAT Vertical
```

```response theme={null}
Row 1:
──────
tid:         (33,61,'51e60bce-6b82-4732-9e1d-b40705ae9ab8')
tid_hash:    11240433987908122467
elapsed:     210.017820947
is_readonly: 1
state:       RUNNING
```

<div id="more-details">
  ## Plus de détails
</div>

Consultez ce [ticket récapitulatif](https://github.com/ClickHouse/ClickHouse/issues/48794) pour accéder à des tests bien plus complets et suivre l’avancement.
