Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e356283
[Spark] Row-level concurrency for concurrent DML via deletion-vector …
sezruby Jul 7, 2026
b64e025
[Spark] Narrow row-level concurrency to sound same-file DV union
sezruby Jul 30, 2026
55f07ab
[Spark] Harden row-level DV-merge concurrency tests + scrub internal …
sezruby Aug 3, 2026
538ef84
Extract row-level concurrency resolution into a self-typed trait
sezruby Aug 4, 2026
1898a55
[Spark] Skip added-file re-scan when no row-level conflict was reconc…
sezruby Aug 4, 2026
6a03f58
[Spark] Add MERGE matched-clause tests to RowLevelConcurrencySuite
sezruby Aug 5, 2026
ccc0f82
Fail safe on DV resolution errors; single-pass action indexing
sezruby Aug 8, 2026
64caa4c
[Spark] Parallelize row-level DV reconciliation across shared files
sezruby Aug 8, 2026
8af17fd
[Spark] Test: multi-file row-level DV reconcile exercises the paralle…
sezruby Aug 8, 2026
e9370cf
[Spark] Document N-way DV-merge correctness; add base-DV chain and Se…
sezruby Aug 13, 2026
0b8f492
[Spark] Simplify RLC integration: prune the winning summary instead o…
sezruby Aug 13, 2026
23a8c77
Only reconcile a shared file when the current txn's reads are unaffected
sezruby Oct 15, 2026
fc37596
Merge remote-tracking branch 'origin/master' into row-level-concurren…
sezruby Oct 15, 2026
cb656e0
Do not reconcile RESTORE or DVs that lose rows
sezruby Oct 21, 2026
5813b9e
Apply the MERGE read shortcut only when the target scan is the only read
sezruby Oct 21, 2026
23e1b37
Skip the read-check scan for a DELETE/UPDATE whose only read is its c…
sezruby Oct 21, 2026
9a25df8
Resolve row-level conflicts after the file-level checks, with packed DVs
sezruby Oct 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,16 @@ object WinningCommitSummary {
}

private[delta] class ConflictChecker(
spark: SparkSession,
protected val spark: SparkSession,
initialCurrentTransactionInfo: CurrentTransactionInfo,
winningCommitSummary: WinningCommitSummary,
// A `var` (reassigned once by [[prepareRowLevelConflictResolution]]) to drop files that are
// resolved at the row level, mirroring how `currentTransactionInfo` is rebased. After that the
// file-level checks run against a summary that never mentions those files, so they need no
// changes.
protected var winningCommitSummary: WinningCommitSummary,
isolationLevel: IsolationLevel)
extends DeltaLogging with ConflictCheckerPredicateElimination {
extends DeltaLogging with ConflictCheckerPredicateElimination
with RowLevelConcurrencyResolution {

protected val dataPath = initialCurrentTransactionInfo.readSnapshot.dataPath
protected val winningCommitVersion = winningCommitSummary.commitVersion
Expand Down Expand Up @@ -352,12 +357,24 @@ private[delta] class ConflictChecker(
// Update the table version in newly added type widening metadata.
updateTypeWideningMetadata()

// Row-level concurrency: set aside the "same physical file" conflicts that merging deletion
// vectors may resolve, so that concurrent DML touching disjoint rows of the same file no
// longer aborts. The file-level checks below then see only the other conflicts. Runs after
// row-ID reassignment so merged files keep stable base row IDs.
prepareRowLevelConflictResolution()

// Data file checks.
checkForAddedFilesThatShouldHaveBeenReadByCurrentTxn()
checkForDeletedFilesAgainstCurrentTxnReadFiles()
checkForDeletedFilesAgainstCurrentTxnDeletedFiles()
resolveTimestampOrderingConflicts()

// Resolve the set-aside files last, so a transaction that aborts on another conflict decodes
// no deletion vector, scans no read and writes no merged deletion vector.
resolveRowLevelConflicts()

recordRowLevelConflictResolution()

// Fold the winning commit into our transaction info before the next attempt: this advances
// `preCommitLatestAMTCheckpointOpt` to the winner's inline AMT checkpoint (when the winner
// wrote one) and clears `currentCommitAttemptAMTCheckpointOpt`.
Expand Down
Loading