How BEGIN CONCURRENT Enables Multi-Version Concurrency Control in Turso

BEGIN CONCURRENT creates snapshot-based MVCC transactions that allow multiple writers to execute simultaneously without exclusive locks, detecting conflicts at commit time through row versioning.

Turso's BEGIN CONCURRENT statement activates the database's multi-version concurrency control (MVCC) engine, enabling high-throughput scenarios where multiple connections can write concurrently without blocking each other. According to the tursodatabase/turso source code, this transaction mode replaces traditional exclusive write locks with snapshot isolation and optimistic conflict detection.

Parsing and Transaction Type Detection

The SQL parser recognizes BEGIN CONCURRENT in parser/src/parser.rs (lines 53,08-53,12) and tags the statement with TransactionType::Concurrent. This classification triggers the VDBE (Virtual Database Engine) to follow the MVCC code path rather than the classic WAL exclusive-lock path.

When the VDBE executes this opcode in core/vdbe/execute.rs (lines 55,500-55,560), it calls begin_mvcc_tx to initialize the MVCC transaction state.

Allocating Transaction IDs Without Write Locks

Unlike standard transactions that acquire exclusive write locks, BEGIN CON CURRENT creates a snapshot-based transaction by allocating a new transaction ID in the MVCC store (MvStore). The connection records this ID via conn.set_mv_tx_for_db, allowing the transaction to proceed without blocking other writers.

This approach enables multiple connections to hold write transactions simultaneously, with each working on its own logical version of the database.

Pinning Consistent WAL Snapshots

To ensure read consistency, the pager executes begin_read_tx() followed by mvcc_refresh_if_db_changed() when the transaction starts. This pins a consistent WAL (Write-Ahead Log) snapshot so that all reads within the transaction see the same database state, even while other writers commit changes.

This mechanism eliminates non-repeatable reads and dirty reads, providing snapshot isolation for the duration of the transaction.

Versioning Rows and Detecting Conflicts

Each writer operates on its own version of rows. When a write attempt occurs, the MVCC layer checks whether the target row version is visible to the current transaction. As documented in core/mvcc/mod.rs (lines 9-25), if another concurrent transaction has already written a newer version, the later transaction receives a LimboError::Busy error and must retry or abort.

This "dirty write" detection prevents lost updates by ensuring transactions only modify rows they have isolated access to.

Commit-Time Validation and First-Writer-Wins

Conflict detection culminates at commit time. The commit_tx_no_conn helper in core/mvcc/database validates that no write-write conflicts occurred during the transaction. If a conflict is detected—meaning another transaction committed changes to the same rows—the later transaction is rolled back.

This enforces a first-writer-wins policy, ensuring that only the first concurrent transaction to commit successfully persists its changes, while conflicting transactions must retry.

Using BEGIN CONCURRENT in Practice

You can leverage BEGIN CONCURRENT through SQL commands or programmatic APIs.

SQL Example

-- Connection A
BEGIN CONCURRENT;
INSERT INTO notes (title, body) VALUES ('A', 'first');
COMMIT;

-- Connection B (runs concurrently)
BEGIN CONCURRENT;
INSERT INTO notes (title, body) VALUES ('B', 'second');
COMMIT;

Rust Binding

use turso::{Connection, Result};

fn concurrent_write(db_url: &str) -> Result<()> {
    let conn = Connection::open(db_url)?;
    conn.execute("BEGIN CONCURRENT")?;          // start MVCC transaction
    conn.execute("INSERT INTO demo(id) VALUES (1)")?;
    conn.execute("COMMIT")?;                    // commit – will abort if conflict
    Ok(())
}

Python Binding

import turso
conn = turso.connect("<url>")
conn.execute("BEGIN CONCURRENT")
conn.execute("INSERT INTO demo VALUES (42)")
conn.commit()          # Turso retries automatically on Busy errors

Key Implementation Files

The BEGIN CONCURRENT functionality spans several critical components:

  • parser/src/parser.rs – Parses the statement and assigns TransactionType::Concurrent
  • core/vdbe/execute.rs – VDBE opcode implementation calling begin_mvcc_tx and managing snapshot refresh (lines 55,500-55,560 and 56,430-56,560)
  • core/mvcc/mod.rs – Documents MVCC guarantees and dirty write detection (lines 9-25)
  • core/mvcc/database/*.rs – Contains MvStore and commit_tx_no_conn for conflict detection
  • tests/integration/mvcc.rs – Integration tests validating concurrent writer behavior

Summary

  • BEGIN CONCURRENT initiates MVCC transactions without acquiring exclusive write locks
  • The parser tags transactions with TransactionType::Concurrent in parser/src/parser.rs
  • Transactions pin consistent WAL snapshots via begin_read_tx() and mvcc_refresh_if_db_changed()
  • Row versioning allows multiple writers to proceed simultaneously, with visibility checks in core/mvcc/mod.rs
  • Write-write conflicts return LimboError::Busy immediately or trigger rollback at commit via commit_tx_no_conn
  • Snapshot isolation guarantees consistent reads throughout the transaction lifetime

Frequently Asked Questions

What is the difference between BEGIN CONCURRENT and a regular transaction in Turso?

Regular transactions acquire exclusive write locks that block other writers until committed, while BEGIN CONCURRENT uses MVCC to allow multiple writers to proceed simultaneously. Regular transactions serialize access through locking, whereas concurrent transactions use optimistic concurrency control with conflict detection at commit time.

How does Turso detect write-write conflicts with BEGIN CONCURRENT?

Turso detects conflicts through the MVCC layer by checking row visibility—when a transaction attempts to write a row that has been modified by a concurrent transaction since the snapshot was taken, the system either returns LimboError::Busy immediately or validates the conflict during commit via the commit_tx_no_conn logic in core/mvcc/database.

What isolation level does BEGIN CONCURRENT provide?

BEGIN CONCURRENT provides snapshot isolation, ensuring that all reads within the transaction see a consistent database state as of the transaction start time. This prevents dirty reads and non-repeatable reads, even while other concurrent writers commit changes.

What happens when two concurrent transactions try to modify the same row?

Turso implements a first-writer-wins policy. The first transaction to commit successfully persists its changes. The second transaction encounters a conflict during commit validation and is rolled back, requiring the application to retry the transaction.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →