Transactions

Important

Les transactions qui écrivent dans les tables Iceberg gérées par le Unity Catalog sont en version préliminaire privée. Pour rejoindre cette préversion, envoyez le formulaire d’inscription en préversion des tables Iceberg managées.

Les transactions vous permettent de coordonner les opérations entre plusieurs instructions et tables SQL. Toutes les modifications aboutissent ensemble ou échouent ensemble, garantissant ainsi la cohérence des données dans vos opérations et tables. Les transactions incluent les propriétés ACID : atomicité, cohérence, isolation et durabilité. Consultez Quelles sont les garanties ACID sur Azure Databricks ?.

Les transactions peuvent être utilisées avec des procédures stockées et des scripts SQL pour créer des charges de travail d’entreposage stratégiques.

L’exemple suivant montre une transaction :

Non interactif

BEGIN ATOMIC
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
  INSERT INTO audit_log VALUES (1, 2, 100, current_timestamp());
END;

Interactif

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
INSERT INTO audit_log VALUES (1, 2, 100, current_timestamp());
COMMIT;

Les trois instructions sont exécutées ensemble. Si une instruction échoue, toutes les modifications sont annulées et Databricks termine la transaction sans effets secondaires.

Pour une pratique pratique avec des transactions, consultez Tutoriel : Coordonner les transactions entre les tables.

Exigences

Pour exécuter des transactions qui s’étendent sur plusieurs instructions ou plusieurs tables :

  • Toutes les tables sur lesquelles on écrit doivent :
  • Utilisez le calcul pris en charge :
    • Pour les transactions non interactives, utilisez n’importe quel entrepôt SQL, calcul serverless ou cluster exécutant Databricks Runtime 18.0 et versions ultérieures.
    • Pour les transactions interactives, utilisez n’importe quel entrepôt SQL.
    • Pour les transactions sur des ressources partagées OpenSharing, utilisez Databricks Runtime 18.1 et versions ultérieures.

Modes de transaction

Azure Databricks prend en charge deux modes de transaction :

Mode Syntaxe Commit Retour arrière Idéal pour
Non interactif Instruction composite ATOMIC Automatique en cas de réussite Automatique en cas d'erreur Séquences fixes, travaux planifiés
Interactif BEGIN TRANSACTION ; COMMIT ; Manuel Manuel Logique conditionnelle, validation et débogage, JDBC, ODBC, PyODBC

Pour obtenir une syntaxe détaillée, des exemples et des modèles d’utilisation pour les deux modes, consultez les modes transactionnels.

Opérations prises en charge

Vous pouvez utiliser les opérations suivantes dans les transactions :

Operation Description
SELECT (sous-sélection) Interroger des données et valider les résultats
Clause VALUES Générer des données de test ou des valeurs constantes
INSERT (y compris toutes les variantes) Ajouter de nouvelles lignes
UPDATE Modifier les lignes existantes
COPY INTO Charger des données à partir d’un fichier dans une table Delta
DELETE FROM Supprimer des lignes
MERGE INTO Modèles Upsert qui combinent l'insertion, la mise à jour et la suppression
USE CATALOG et USE SCHEMA Définir le catalogue ou le schéma actuel pour les instructions de la transaction
EXECUTE IMMEDIATE Exécuter une instruction SQL que vous construisez dynamiquement au moment de l’exécution
DESCRIBE TABLE Retourner des métadonnées sur une table, telles que ses colonnes et ses propriétés
SHOW COLUMNS Répertorier les colonnes d’une table
GET DIAGNOSTICS, instruction Récupérer des informations de diagnostic, telles que l’état de la transaction active ou le nombre de lignes affectées par l’instruction la plus récente

Sources de lecture prises en charge et récepteurs d’écriture

Les transactions vous permettent de lire des tables de catalogue Unity (Delta Lake et Iceberg), des tables de streaming, des vues et des vues matérialisées.

En raison des garanties ACID, les formats de table ouverts, tels que Delta Lake et Iceberg, sont pris en charge dans les transactions en tant que sources de lecture et récepteurs d’écriture. Pour lire à partir de sources non transactionnelles, utilisez l’indicateur allow_nontransactional_read . Consultez Lecture à partir de sources non transactionnelles et Exemple : lecture non transactionnelle.

Lecture depuis des sources non transactionnelles

Avertissement

Les lectures non transactionnelles ne sont pas reproductibles. Les modifications simultanées apportées aux données sources pendant la transaction peuvent entraîner des lectures incohérentes.

Les transactions vous permettent de lire à partir de sources non transactionnelles. Les sources non transactionnelles incluent des tables externes utilisant des formats de fichiers Parquet, Avro, CSV et JSON et des tables fédérées à l’aide de JDBC. Pour lire des sources non transactionnelles, référencez la source par nom et utilisez l’indicateur allow_nontransactional_read .

Dans une transaction, vous pouvez également interroger le information_schema.

Vous pouvez lire des fichiers directement avec la fonction read_files renvoyant une table.

L’accès basé sur le chemin n’est pas pris en charge. Si, à la place, vous faites référence à un fichier directement à l’aide de son chemin d’accès, par exemple FROM parquet.`/path/to/data`, la transaction échoue avec l’erreur PATH_BASED_ACCESS.

L’exemple de code suivant montre comment utiliser l’indicateur sur une table externe à l’aide de JSON :

BEGIN TRANSACTION;
-- Non-transactional source, hint required
INSERT INTO transactional_table
SELECT col1, col2
FROM external_json_table
WITH (allow_nontransactional_read = true);

COMMIT;

Exemple : lecture non transactionnelle

L’exemple suivant montre une lecture non transactionnelle à partir d’une table externe à l’aide de Parquet. Cet exemple nécessite que vous disposiez d’un emplacement externe existant avec un accès en lecture et en écriture.

Consultez Se connecter à un emplacement externe Azure Data Lake Storage Gen2 (ADLS Gen2).

Pour enregistrer la source Parquet en tant que table externe nommée, exécutez la commande suivante :

CREATE TABLE main.default.external_parquet_table
USING PARQUET
LOCATION 'abfss://my-container@my-storage-account.dfs.core.windows.net/path/to/data'; -- existing external location

Pour lire à la fois une source Parquet non transactionnelle et une table managée à l’aide de Delta Lake dans une transaction, exécutez ce qui suit :

BEGIN ATOMIC
-- Non-transactional source, hint required
INSERT INTO transactional_table
SELECT col1, col2
FROM external_parquet_table
WITH (allow_nontransactional_read = true);

-- Managed table source, no hint is required
INSERT INTO another_table
SELECT * FROM managed_delta_table;
END;

Isolation des transactions

Les transactions permettent des lectures répétables dans l’ensemble des instructions. Lorsque vous accédez à une table dans une transaction, Azure Databricks capture un instantané cohérent de cette table au premier accès. Toutes les lectures suivantes de cette table utilisent cet instantané. Vos lectures restent donc cohérentes même si d’autres utilisateurs modifient simultanément les mêmes tables.

Dans l’exemple suivant, la première requête vers products dans la transaction capture un instantané cohérent :

Non interactif

BEGIN ATOMIC
  SELECT * FROM products WHERE product_id = 1001;
  SELECT * FROM products WHERE product_id = 1001;
END;

Interactif

BEGIN TRANSACTION;
SELECT * FROM products WHERE product_id = 1001;
SELECT * FROM products WHERE product_id = 1001;
COMMIT;

Ensuite, supposons qu’un autre utilisateur mette simultanément à jour la ligne pour product_id = 1001 avant que la deuxième requête ne commence :

UPDATE products SET price = 29.99 WHERE product_id = 1001;

Étant donné que l’instantané a été capturé au premier accès, la deuxième requête pour products renvoyer la ligne d’origine, et non la ligne mise à jour.

Détection des conflits et concurrence

Azure Databricks utilise le contrôle de la concurrence optimiste. Les transactions continuent sans verrouillage, et les conflits sont détectés au moment de la validation. Lorsque vous validez, Azure Databricks vérifie si d’autres transactions ont modifié les mêmes données après le début de votre transaction. Si des conflits existent, votre transaction échoue. Pour les transactions non interactives, l'annulation se produit également automatiquement. Pour les transactions interactives, vous devez exécuter ROLLBACK explicitement pour effacer l’état de la transaction avant de commencer une nouvelle transaction.

Les transactions non interactives prennent en charge la concurrence au niveau des lignes. Deux transactions peuvent modifier des lignes différentes dans le même fichier de données sans conflit lorsque la concurrence au niveau des lignes est activée sur les tables cibles.

Les transactions interactives supportent la concurrence au niveau des tables.

Scénarios de conflit

Scénario Description
Conflicts write-write Deux transactions mettent à jour ou suppriment les mêmes lignes.
Conflits de lecture-écriture Une autre transaction a modifié les lignes lues par votre transaction. S’applique uniquement à l’isolation sérialisable.
Conflits de lecture fantôme Une autre transaction a inséré de nouvelles lignes correspondant à un prédicat que votre transaction a lu. S’applique aux niveaux d’isolation WriteSerializable et Serializable.
Conflits de métadonnées Une autre transaction a modifié le schéma de table ou les propriétés.

Pour plus d’informations sur les niveaux d’isolation et la résolution des conflits pour les transactions, consultez les modes de transaction. Pour plus d’informations sur les niveaux d’isolation et le comportement de conflit d’écriture pour les tables Delta Lake sur Azure Databricks, consultez les recommandations d'optimisation sur Azure Databricks.

Comment les transactions apparaissent dans le journal Delta

Chaque transaction réussie apparaît sous la forme d’une entrée unique dans le journal Delta de la table, quel que soit le nombre d’instructions individuelles exécutées dans la transaction. Cela permet d’assurer une piste d’audit claire et simplifie les opérations de retour en arrière.

Les opérations individuelles au sein d’une transaction sont disponibles sous forme de métadonnées JSON dans l’entrée du journal Delta pour la transaction.

Gestion des erreurs et retour arrière

Le tableau suivant décrit comment les restaurations d’erreurs se produisent pour les deux types de transactions :

Scénario Comportement des transactions non interactives Comportement des transactions interactives
Échec de l’instruction Toute instruction qui génère une erreur provoque une annulation automatique immédiate. Vous devez exécuter explicitement ROLLBACK pour ignorer les modifications si la session est toujours active.
Échec de la logique de validation ou des règles métier Utilisez SIGNAL pour lancer une exception et déclencher un retour en arrière automatique. Exécutez ROLLBACK pour ignorer les modifications.
Déconnexion de session La transaction est automatiquement annulée. La transaction est automatiquement annulée.
Délai d'expiration Se réinitialise automatiquement après un délai de 48 heures. Revient automatiquement après 10 minutes d'absence d'activité ou 48 heures de durée totale (voir Limitations). La transaction est terminée sans effets secondaires, mais vous devez exécuter explicitement ROLLBACK pour effacer l’état de la transaction si la session est toujours active.

Pour les transactions interactives, vous pouvez annuler explicitement à l’aide de l’instruction ROLLBACK. Cela vous permet d’ignorer les modifications en fonction de la logique de validation ou des règles métier, ou après un échec d’instruction lorsque la session reste active.

Bonnes pratiques

Suivez ces pratiques pour réduire les conflits et optimiser les performances des transactions.

Éviter les conflits

  • Conserver les transactions courtes : les transactions longues augmentent la probabilité de conflit et conservent les ressources plus longtemps.
  • Valider tôt : vérifiez les conditions préalables au début d’une transaction pour échouer rapidement.
  • Utilisation BEGIN ATOMIC pour la concurrence au niveau des lignes : les transactions non interactives (BEGIN ATOMIC ... END;) détectent les conflits au niveau de la ligne, ce qui réduit les conflits par rapport à la détection au niveau de la table utilisée par les transactions interactives. Consultez les transactions non interactives.
  • Implémentez un mécanisme de nouvelle tentative : une transaction peut échouer à tout moment à cause d’un conflit. Générez une logique de nouvelle tentative dans votre application et réessayez les transactions ayant échoué avec de nouvelles données.
  • Démarrez chaque session interactive avec une restauration : exécutez ROLLBACK au début d’une session interactive pour effacer tout état de transaction préexistant.

Utiliser des transactions de différents clients

Les transactions fonctionnent sur différentes interfaces clientes :

Limites

Les limitations suivantes s’appliquent aux transactions :

Limitation Description
Conflits de transactions interactives Les transactions interactives (BEGIN TRANSACTION ; ... COMMIT ;) utilisent une détection de conflit plus conservatrice que les transactions non interactives et peuvent provoquer un conflit au niveau de la table, à l’exception des opérations INSERT qui ne lisent pas à partir de la table cible. Utilisez des transactions non interactives (instruction composée ATOMIC) lorsque la détection de conflit au niveau des lignes est importante. Consultez les transactions non interactives.
Objectifs d’écriture Vous ne pouvez écrire que dans les tables Delta ou Iceberg gérées par le catalogue Unity qui ont la fonctionnalité de table catalogManaged activée. Consultez les validations de catalogue.
Opérations DDL non prises en charge Exécutez des opérations DDL, telles que CREATE TABLE, ALTER TABLEou DROP TABLE, en dehors des transactions. Pour connaître les opérations prises en charge par les transactions, consultez Opérations prises en charge.
Certaines opérations de métadonnées non prises en charge Certaines opérations de métadonnées ne fonctionnent pas à l’intérieur des transactions, quel que soit le protocole. Cela inclut les appels de métadonnées basés sur le RPC Thrift (comme les méthodes JDBC DatabaseMetaData et les fonctions de catalogue ODBC), les commandes basées sur SQL qui répertorient des objets (telles que SHOW TABLES et SHOW DATABASES), ainsi que les requêtes SELECT sur les tables système. Exécutez ces opérations de métadonnées en dehors des transactions.
COPY INTO Concurrence Une transaction exécutant une commande COPY INTO échoue si une autre commande COPY INTO s’exécute simultanément pour écrire dans la même table et que celle-ci est validée en premier.
Concurrence au niveau des lignes pour MERGE La concurrence au niveau ligne pour les opérations MERGE n’est pas prise en charge sur AWS GovCloud ni sur les clusters mono-utilisateur (dédiés). Sur ces plateformes, les opérations MERGE reposent sur une concurrence au niveau de la table. Consultez la concurrence au niveau des lignes.
Limites de table et d’affichage Une transaction peut lire ou écrire jusqu’à 100 tables combinées et lire jusqu’à 100 vues. Chaque table peut avoir jusqu’à 100 validations intermédiaires dans une transaction.
Voyage dans le temps non pris en charge Vous ne pouvez pas utiliser le voyage dans le temps dans une transaction.
Délai d’inactivité Les transactions interactives sont annulées après 10 minutes d’inactivité. La transaction est terminée sans effets secondaires, mais vous devez exécuter explicitement ROLLBACK pour effacer l’état de la transaction si la session est toujours active.
Lignage Les transactions émettent la traçabilité lorsque chaque lecture et écriture ont lieu. Les événements de lignée persistent même si la transaction est annulée.
Durée maximale Toutes les transactions sont automatiquement annulées après 48 heures de durée totale. Pour les transactions interactives, la transaction est arrêtée sans effets secondaires, mais vous devez exécuter explicitement ROLLBACK pour effacer l’état de la transaction si la session est toujours active.
Configuration requise des tables partagées OpenSharing Les fournisseurs OpenSharing doivent partager une table WITH HISTORY pour permettre aux destinataires d’exécuter des transactions dessus. Les destinataires peuvent exécuter des transactions à l’aide de n’importe quel type de calcul.
Restrictions de calcul du destinataire OpenSharing Les destinataires Azure Databricks ne peuvent exécuter des transactions que sur des vues partagées, des vues matérialisées, des tables de flux et des tables étrangères non-Iceberg. Les destinataires du même compte Azure Databricks que leur fournisseur doivent utiliser le calcul partagé ou serverless. Les destinataires d’un autre compte doivent utiliser le calcul sans serveur.
Conflit de la table source OpenSharing Les destinataires OpenSharing ne peuvent pas référencer une vue partagée et une table partagée qui référence la même table source au sein d’une seule transaction.

Ressources supplémentaires