transactional memory
**Transactional Memory** is the **concurrency control mechanism that allows programmers to declare blocks of code as atomic transactions — where the runtime (hardware or software) ensures that either all memory operations within the transaction commit atomically and become visible to other threads, or the transaction aborts and retries with no visible side effects, providing a programming model far simpler than fine-grained locking while avoiding deadlocks entirely**.
**The Locking Problem Transactional Memory Solves**
Fine-grained locking maximizes concurrency but is error-prone: lock ordering must be maintained (or deadlocks occur), lock granularity decisions are complex, and composing two lock-based data structures into a single atomic operation is nearly impossible without exposing internal locks. Transactional memory lets the programmer simply say "execute this block atomically" — the system handles the concurrency.
**Hardware Transactional Memory (HTM)**
- **Mechanism**: The processor tracks all loads and stores within a transaction using the cache coherence protocol. If no other thread touches the same cache lines, the transaction commits atomically (all writes become visible at once). If a conflict is detected (another thread wrote to a line read by the transaction, or vice versa), the transaction aborts — all changes are discarded and execution restarts.
- **Intel TSX (Transactional Synchronization Extensions)**:
- **HLE (Hardware Lock Elision)**: XACQUIRE/XRELEASE prefixes speculatively elide a lock — execute the critical section transactionally without acquiring the lock. If the transaction succeeds, the lock was never contended. If it aborts, fall back to actually acquiring the lock.
- **RTM (Restricted Transactional Memory)**: XBEGIN/XEND explicitly demarcate transactions. XBEGIN returns a status code if the transaction aborts (conflict, capacity overflow, interrupt).
- **Limitations**: HTM transactions must fit in L1 cache (tracked per cache line). Context switches, interrupts, and certain instructions abort transactions. HTM is a "best effort" mechanism — software fallback (lock) is always required.
**Software Transactional Memory (STM)**
- **Mechanism**: All reads and writes within a transaction are logged in a transaction-local buffer. At commit time, the STM runtime validates that no other transaction has modified the read set (optimistic concurrency). If validation succeeds, writes are applied atomically. If validation fails, the transaction aborts and retries.
- **Implementations**: Haskell STM (the most elegant — type system prevents I/O inside transactions), Clojure refs, GCC __transaction_atomic extension.
- **Overhead**: STM adds 2-10x runtime overhead for read/write logging and validation. Acceptable for complex concurrent data structures; too expensive for simple critical sections where a mutex is cheaper.
**Composability**
The killer advantage of transactional memory: two transactional operations can be composed into a single atomic operation simply by wrapping both calls in a transaction. This is impossible with locks (you'd need access to both operations' internal locks).
Transactional Memory is **the programmer-friendly concurrency abstraction that trades runtime overhead for programming simplicity and correctness** — eliminating lock management, deadlock risk, and composability limitations by letting the system speculatively execute concurrent code and roll back conflicts automatically.