Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Transaction Workspace

The transaction workspace system provides ACID transaction semantics for tensor_chain operations. It enables isolated execution with snapshot-based reads and atomic commits via delta tracking.

Overview

Key features:

  • Snapshot isolation: Reads see consistent state from transaction start
  • Delta tracking: Changes tracked as semantic embeddings for conflict detection
  • Atomic commit: All-or-nothing via block append
  • Cross-shard coordination: Two-phase commit (2PC) for distributed transactions
flowchart TD
    A[Client] -->|begin| B[TransactionWorkspace]
    B -->|snapshot| C[Checkpoint]
    B -->|add_operation| D[Operations]
    B -->|compute_delta| E[EmbeddingState]
    E --> F{Conflict Check}
    F -->|orthogonal| G[Commit]
    F -->|conflicting| H[Rollback]
    H -->|restore| C

Workspace Lifecycle

State Machine

stateDiagram-v2
    [*] --> Active: begin()
    Active --> Active: add_operation()
    Active --> Committing: mark_committing()
    Committing --> Committed: mark_committed()
    Committing --> Failed: error
    Active --> RolledBack: rollback()
    Failed --> [*]
    Committed --> [*]
    RolledBack --> [*]

State Descriptions

StateDescription
ActiveOperations can be added
CommittingCommit in progress, no more operations
CommittedSuccessfully committed to the chain
RolledBackRolled back, state restored from checkpoint
FailedError during commit, requires manual resolution

Transaction Operations

Basic Usage

#![allow(unused)]
fn main() {
use tensor_chain::{TensorStore, TransactionWorkspace};
use tensor_chain::block::Transaction;

let store = TensorStore::new();

// Begin transaction
let workspace = TransactionWorkspace::begin(&store)?;

// Add operations
workspace.add_operation(Transaction::Put {
    key: "user:1".to_string(),
    data: vec![1, 2, 3],
})?;

workspace.add_operation(Transaction::Put {
    key: "user:2".to_string(),
    data: vec![4, 5, 6],
})?;

// Check affected keys
let keys = workspace.affected_keys();
assert!(keys.contains("user:1"));

// Commit or rollback
workspace.mark_committing()?;
workspace.mark_committed();
}

Operation Types

OperationDescriptionAffected Key
PutInsert or update keyThe key itself
DeleteRemove keyThe key itself
UpdateModify existing keyThe key itself

Delta Tracking

The workspace tracks changes as semantic embeddings using the EmbeddingState machine. This enables conflict detection based on vector similarity.

Before/After Embedding Flow

flowchart LR
    A[begin] -->|capture| B[before embedding]
    B --> C[operations]
    C -->|compute| D[after embedding]
    D --> E[delta = after - before]
    E --> F[DeltaVector]

Computing Deltas

#![allow(unused)]
fn main() {
// Set the before-state embedding at transaction start
workspace.set_before_embedding(before_embedding);

// ... execute operations ...

// Compute delta at commit time
workspace.compute_delta(after_embedding);

// Get delta for conflict detection
let delta_vector = workspace.to_delta_vector();
}

Delta Vector Structure

FieldTypeDescription
embeddingVec<f32>Semantic change vector
affected_keysHashSet<String>Keys modified by transaction
tx_idu64Transaction identifier

Isolation Levels

The workspace provides snapshot isolation by default. All reads within a transaction see the state captured at begin().

LevelDirty ReadsNon-RepeatablePhantom Reads
Snapshot (default)NoNoNo

Snapshot Mechanism

  1. begin() captures the store state as a binary checkpoint
  2. All reads within the transaction see this snapshot
  3. rollback() restores the snapshot if needed
  4. Checkpoint is discarded after commit/rollback

Lock Management

For distributed transactions, the LockManager provides key-level locking with deadlock prevention.

Lock Ordering

To prevent deadlocks, always acquire locks in this order:

  1. pending - Transaction state map
  2. lock_manager.locks - Key-level locks
  3. lock_manager.tx_locks - Per-transaction lock sets
  4. pending_aborts - Abort queue

Lock Configuration

ParameterDefaultDescription
default_timeout30sLock expiration time
timeout_ms5000Transaction timeout

Lock Acquisition

#![allow(unused)]
fn main() {
// Try to acquire locks for multiple keys
match lock_manager.try_lock(tx_id, &keys) {
    Ok(lock_handle) => {
        // Locks acquired successfully
    }
    Err(conflicting_tx) => {
        // Another transaction holds a lock
    }
}
}

Cross-Shard Coordination

Distributed transactions use two-phase commit (2PC) for cross-shard coordination.

2PC Protocol

sequenceDiagram
    participant C as Coordinator
    participant S1 as Shard 1
    participant S2 as Shard 2

    Note over C: Phase 1: Prepare
    C->>S1: TxPrepare(ops, delta)
    C->>S2: TxPrepare(ops, delta)
    S1->>S1: acquire locks
    S2->>S2: acquire locks
    S1->>S1: check conflicts
    S2->>S2: check conflicts
    S1->>C: Vote(Yes, delta)
    S2->>C: Vote(Yes, delta)

    Note over C: Phase 2: Commit
    C->>S1: TxCommit
    C->>S2: TxCommit
    S1->>C: Ack
    S2->>C: Ack

Transaction Phases

PhaseDescription
PreparingAcquiring locks, computing deltas
PreparedAll participants voted YES
CommittingFinalizing the commit
CommittedSuccessfully committed
AbortingRolling back due to NO vote or timeout
AbortedSuccessfully aborted

Prepare Vote Types

VoteDescriptionAction
YesReady to commit, locks acquiredProceed to Phase 2
NoCannot commit (validation failed)Abort
ConflictDetected semantic conflictAbort

Conflict Detection

The workspace uses delta embeddings to detect conflicts based on vector similarity.

Orthogonality Check

Two transactions are considered orthogonal (non-conflicting) if their delta vectors have low cosine similarity:

similarity = cos(delta_A, delta_B)
orthogonal = abs(similarity) < threshold

Configuration

ParameterDefaultDescription
orthogonal_threshold0.1Max similarity for orthogonal
merge_window_ms60000Window for merge candidates

Merge Candidates

The TransactionManager can find transactions eligible for parallel commit:

#![allow(unused)]
fn main() {
// Find orthogonal transactions that can be merged
let candidates = manager.find_merge_candidates(
    &workspace,
    0.1,      // orthogonal threshold
    60_000,   // merge window (60s)
);

// Candidates are sorted by similarity (most orthogonal first)
for candidate in candidates {
    println!("Tx {} similarity: {}", candidate.workspace.id(), candidate.similarity);
}
}

Error Handling

ErrorCauseRecovery
TransactionFailedOperation on non-active workspaceCheck state first
WorkspaceErrorSnapshot/restore failedCheck store health
LockConflictAnother tx holds the lockRetry with backoff
TimeoutTransaction exceeded timeoutIncrease timeout

Usage Example

Complete Transaction Flow

#![allow(unused)]
fn main() {
use tensor_chain::{TensorStore, TransactionManager};
use tensor_chain::block::Transaction;

// Create manager
let store = TensorStore::new();
let manager = TransactionManager::new();

// Begin transaction
let workspace = manager.begin(&store)?;

// Add operations
workspace.add_operation(Transaction::Put {
    key: "account:1".to_string(),
    data: serialize(&Account { balance: 100 }),
})?;

workspace.add_operation(Transaction::Put {
    key: "account:2".to_string(),
    data: serialize(&Account { balance: 200 }),
})?;

// Set embeddings for conflict detection
workspace.set_before_embedding(vec![0.0; 128]);
workspace.compute_delta(compute_state_embedding(&store));

// Check for conflicts with other active transactions
let candidates = manager.find_merge_candidates(&workspace, 0.1, 60_000);
if candidates.is_empty() {
    // No orthogonal transactions, commit alone
    workspace.mark_committing()?;
    workspace.mark_committed();
} else {
    // Can merge with orthogonal transactions
    // ... merge logic ...
}

// Remove from manager
manager.remove(workspace.id());
}

Source Reference

  • tensor_chain/src/transaction.rs - TransactionWorkspace, TransactionManager
  • tensor_chain/src/distributed_tx.rs - 2PC coordinator, LockManager
  • tensor_chain/src/embedding.rs - EmbeddingState machine
  • tensor_chain/src/consensus.rs - DeltaVector, conflict detection