dolthub / dolthub/doltgresql

Support atomic commits spanning local and nonlocal tables

Open
#3,232 2 comments 0 reactions 1 assignee Claimed by @zachmu View on GitHub
customer issue enhancement
Dominant language
Go
Stars
2.1k
Forks
73
Avg merge
1d 10h
Merged PRs (30d)
129

Description

Please add a supported way for one SQL transaction to modify versioned tables on the active branch and writable nonlocal tables targeting another local branch, then commit both sets of changes atomically.

Doltgres currently rejects this transaction with:

```text
ERROR: Cannot commit changes on more than one branch / database
```

The current documentation only supports `options = 'immediate'`. A manual or deferred mode is insufficient unless its publication operation participates in that same atomic commit.

## Repro

Reproduced with `dolthub/doltgresql:1.3.0`:

```sql
CREATE TABLE local_items (
id integer PRIMARY KEY,
value text NOT NULL
);

CREATE TABLE global_items (
id integer PRIMARY KEY,
value text NOT NULL
);

INSERT INTO dolt_nonlocal_tables (
table_name,
target_ref,
ref_table,
options
) VALUES (
'global_items',
'main',
'global_items',
'immediate'
);

SELECT dolt_commit('-Am', 'set up local and nonlocal tables');
SELECT dolt_branch('feature', 'HEAD');
SELECT dolt_checkout('feature');

BEGIN;
INSERT INTO local_items VALUES (1, 'local');
INSERT INTO global_items VALUES (1, 'nonlocal');
COMMIT;
```

The final `COMMIT` fails:

```text
ERROR: Cannot commit changes on more than one branch / database
```

The server correctly rolls back both inserts, but there is no supported mode in which the transaction can succeed atomically. The same failure occurs when `dolt_transaction_commit` is enabled.

## Use case

The app we're working on stores application-wide metadata on `main` through nonlocal tables while keeping versioned data on per-user branches. Operations such as versioned data creation/edit, metadata edit, etc update both nonlocal tables and versioned tables in users' branches.

Splitting these operations into separate transactions in certain cases can leave global metadata describing a state that the branch never committed, or advance the branch without publishing its corresponding metadata.

## Required behavior

For our app, supported nonlocal-table mode is required with these semantics:

- Before `COMMIT`, neither write is visible outside the transaction.
- On success, the local write is applied to the active branch and the nonlocal write is applied to its target branch.
- With `dolt_transaction_commit = on`, advancing the active branch revision is part of the same atomic outcome.
- If either destination conflicts or fails, neither working set changes and no branch revision advances.
- Concurrent transactions touching the same nonlocal target participate in conflict detection.

It is acceptable for a manual mode to require an explicit push or publication call, provided that call can be included in the same atomic transaction as the active branch commit.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.