Merk
Tilgang til denne siden krever autorisasjon. Du kan prøve å logge på eller endre kataloger.
Tilgang til denne siden krever autorisasjon. Du kan prøve å endre kataloger.
Når flere Fabric-notatbøker, pipelines eller Spark-jobber skriver til samme Delta-tabell samtidig, bruker Delta Lake optimistisk samtidighetskontroll (OCC) for å holde tabellen konsistent. Hver transaksjon leser et øyeblikksbilde, skriver nye filer, og validerer deretter at ingen konfliktfylt commit har skjedd imellom. Hvis en konflikt oppdages, mislykkes transaksjonen med et unntak i stedet for å korrumpere data.
Denne artikkelen dekker praktiske mønstre for å håndtere samtidige skrivinger i Fabric. For en fullstendig spesifikasjon av OCC-protokollen, se Delta Lake samtidighetskontroll (åpen kildekode-dokumentasjon).
Isolasjonsnivåer
Alle Delta-tabeller bruker det serialiserbare isolasjonsnivået. Serializable er det strengeste nivået og det eneste som støttes. Den sikrer at resultatet av samtidige transaksjoner er identisk med en sekvensiell utførelsesrekkefølge.
Delta Lake bruker også et internt SnapshotIsolation-nivå for operasjoner som ikke endrer logiske data (som OPTIMIZE). SnapshotIsolation hopper over sjekken av samtidige appender, slik at komprimering kan fortsette uten å kollidere med samtidige innsettinger. Du konfigurerer ikke SnapshotIsolation direkte – Delta Lake bruker det automatisk når det er hensiktsmessig.
Med Serializable isolasjon kan et samtidig blindt tillegg (INSERT INTO) komme i konflikt med a MERGE eller UPDATE som leser samme partisjon.
Hvilke operasjoner er konflikt
Ikke alle samtidige skrivinger er i konflikt. Den viktigste faktoren er om to operasjoner berører de samme underliggende filene.
| Samtidig par | Konflikt? | Hvorfor |
|---|---|---|
To INSERT (vedlagt) operasjoner |
Nei | Hver legger til nye filer uten å lese eksisterende (blind append). |
INSERT + OPTIMIZE |
Nei |
OPTIMIZE commits at SnapshotIsolation fordi den ikke endrer logiske data, så den hopper over sjekken av samtidige tillegg helt. Tillegg legger til nye filer som ikke overlapper med filer som komprimeres. |
To, UPDATEDELETE, eller MERGE operasjoner |
Ja, hvis de leser eller endrer overlappende filer | Hver skriver om filer, så den andre forfatterens snapshot blir utdatert. |
OPTIMIZE + UPDATE/DELETE/MERGE |
Ja, hvis de berører de samme filene |
OPTIMIZE fjerner og legger til filer igjen (med dataChange=false). Hvis en datamodifikasjonsoperasjon også leser de samme filene, blir a ConcurrentDeleteReadException hevet. |
To OPTIMIZE løp |
Ja, hvis de velger de samme filene | Begge forsøker å fjerne og omskrive det samme settet med filer, noe som utløser en ConcurrentDeleteDeleteException. |
INSERT + MERGE/UPDATE/DELETE |
Ja, hvis dataendringsoperasjonen leser samme partisjon | Under Serializable, kan et blind tillegg komme i konflikt med samtidige dataendringer hvis operasjonen leste en partisjon som appenden skrev til. |
Tips
Append-only pipelines (INSERT INTO, df.write.mode("append")) er den enkleste måten å unngå konflikter helt på. Hvis arbeidsmengden din kan legges til først og avstemmes senere, eliminerer du skriv-skriv-konflikt.
Isoler skribenter med partisjonering
Den vanligste måten å kjøre samtidig DML mot samme tabell uten konflikter på, er å dele tabellen etter kolonnen som skiller forfatterne dine, og deretter inkludere den kolonnen i hver operasjonsbetingelse. Når hver forfatter retter seg mot en forskjellig partisjon, berører operasjonene disjunkte filsett og kommer ikke i konflikt.
Et typisk scenario: flere pipelines behandler hver data for en annen forretningsenhet eller leietaker. Partisjoner etter den dimensjonen og fest hver rørledning MERGE til sin partisjon.
-- Each pipeline targets its own partition, so concurrent runs don't conflict
MERGE INTO events AS target
USING staged AS source
ON target.event_id = source.event_id
AND target.business_unit = 'EMEA'
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *
Important
Partisjonskolonnen må vises i selve sammenslåingsbetingelsen—ikke bare i kildedataene. Uten den kan ikke Delta Lake ved validering fastslå at de to operasjonene berørte disjunkte filsett, og konfliktsjekkeren behandler operasjonen som en full-tabell-lesing.
For mer detaljer om partisjoneringsstrategier, se Partitionering for Delta-tabeller.
Innebygd commit retry
Delta Lake prøver automatisk en commit på nytt når den oppdager at en annen transaksjon er gjort først. Ved hvert forsøk leser den vinnende commit, kjører konfliktsjekkeren, og – hvis det ikke finnes noen logisk konflikt – prøver den commit på nytt ved neste tilgjengelige versjon. Denne prosessen gjentas transparent uten noen handling fra koden din.
En logisk konflikt (for eksempel to operasjoner som skriver om samme fil) kan ikke løses automatisk. Gjenprøvingen reiser ett av unntakene listet i Common conflict-unntakene. Mange kollisjoner med forbigående versjoner – som to blinde tillegg som konkurrerer om samme versjonsplass – løses imidlertid automatisk og vises aldri i applikasjonen din.
Vanlige unntak for konflikt
Når en konflikt oppdages, oppretter Delta Lake et spesifikt unntak. Å forstå hvilket unntak du ser hjelper deg å identifisere den egentlige årsaken.
| Unntak | Hva har skjedd |
|---|---|
ConcurrentAppendException |
En annen forfatter la til filer i en partisjon (eller filsett) som operasjonen din leste. Vanlig når en MERGE kjører mot en partisjon som også mottar inserts fra en annen pipeline. Under Serializable isolasjon kan selv blinde tillegg (vanlige INSERT operasjoner) utløse dette unntaket. |
ConcurrentDeleteReadException |
En annen forfatter slettet eller skrev om en fil som operasjonen din leste. Typisk når OPTIMIZE filer komprimeres som en samtidig UPDATE eller MERGE også leste, eller når to datamodifikasjonsoperasjoner overlapper på de samme radene. |
ConcurrentDeleteDeleteException |
Begge operasjonene forsøkte å slette eller omskrive den samme filen. Ofte forårsaket av overlappende OPTIMIZE kjøringer eller to pipelines som omskriver samme partisjon samtidig. |
ConcurrentWriteException |
En generell konflikt oppstår når en annen transaksjon ble forpliktet til samme tabellversjon før konfliktløsning kunne kjøres—for eksempel under en oppgradering fra filsystem til managed commits. |
MetadataChangedException |
Tabellens skjema eller egenskaper endres midt i en transaksjon ALTER TABLE – for eksempel en samtidig eller skjema-evolusjonsskriving. |
ConcurrentTransactionException |
To Structured Streaming-spørringer med samme sjekkpunktplassering ble skrevet til tabellen samtidig. Dedupliser strømmeoppdragene dine eller bruk ulike sjekkpunkt-veier. |
ProtocolChangedException |
En samtidig transaksjon oppgraderte eller nedgraderte tabellprotokollen mens den nåværende transaksjonen også forsøkte en protokollendring. Kan også oppstå når en tabellfunksjon droppes samtidig. |
Vanlige strategier for å unngå skrivekonflikter
Aktiver automatisk komprimering
Automatisk komprimering kjører synkront som en del av skriveoperasjoner. Synkron komprimering forhindrer at separat planlagte komprimeringsjobber overlapper med dataendringsoperasjoner og dermed forårsaker samtidige skriverunntak.
Planlegg vedlikehold utenfor skrivevinduer
OPTIMIZE og VACUUM kan komme i konflikt med samtidige dataendringsoperasjoner. I Fabric, planlegg notatbokjobber eller pipeline-aktiviteter for tabellkompaktering og VACUUM under lavaktivitetsvinduer – for eksempel etter at nattlig inntak er fullført, ikke underveis.
Bruk append + merge-mønstre
For høy-samtidig-inntak, land rådata med kun append-skriving inn i en staging-tabell (ingen konflikter mulig), og kjør deretter en enkelt MERGE jobb for å avstemme til måltabellen. Mønsteret serialiserer den konfliktutsatte operasjonen samtidig som inntaket holdes helt parallelt.
Legg til retry-logikk for logiske konflikter
Den innebygde commit retry håndterer transiente versjonskollisjoner automatisk, men logiske konflikter – der to operasjoner faktisk overlapper hverandre – utløser et unntak. Fordi Delta Lake aldri produserer delvise skrivinger, er en mislykket transaksjon trygg å prøve på nytt på applikasjonsnivå. For pipelines hvor det er forventet sporadiske logiske konflikter, pakk inn skrivelogikken i retry:
from delta.exceptions import ConcurrentAppendException
import time
# Retry with backoff on transient concurrent write conflicts
max_retries = 3
for attempt in range(max_retries):
try:
spark.sql("MERGE INTO target USING source ON ...")
break
except ConcurrentAppendException:
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
else:
raise
Velg riktig layoutstrategi
Væskeklynging og partisjonering løser ulike problemer. Liquid clustering optimaliserer filoppsettet for leseytelse. Oppdeling skaper fysiske grenser som forhindrer samtidige konflikter mellom forfattere. Hvis arbeidsmengden din trenger begge deler, partisjoner du etter writer-isolation-kolonnen og bruker Z-Order innenfor hver partisjon for leseytelse.