How to Simulate Distributed Transactions in Python with a Mock

Model distributed transaction behavior with a mock Transaction class that supports commit, rollback, and failure simulation.

Medium Python 3.9+ Aug 9, 2026 Database scaling & optimization 13 views 0 copies

Python code

50 lines
Python 3.9+
class Transaction:
    def __init__(self, id):
        self.id = id
        self.operations = []
        self.committed = False

    def add_operation(self, op, data):
        self.operations.append((op, data))

    def commit(self):
        if not self.operations:
            raise ValueError("No operations to commit")
        self.committed = True
        print(f"Transaction {self.id} committed with {len(self.operations)} operations")

    def rollback(self):
        self.operations.clear()
        print(f"Transaction {self.id} rolled back")

    def simulate_failure(self):
        print(f"Transaction {self.id} failed before commit")
        self.rollback()


class FakeDatabase:
    def __init__(self):
        self.transactions = []

    def execute(self, transaction):
        try:
            transaction.commit()
            self.transactions.append(transaction)
        except ValueError as e:
            print(f"Error: {e}")


if __name__ == "__main__":
    db = FakeDatabase()
    txn1 = Transaction("T1")
    txn1.add_operation("INSERT", {"user": "alice", "amount": 100})
    txn1.add_operation("UPDATE", {"balance": 150})

    txn2 = Transaction("T2")
    txn2.add_operation("DELETE", {"id": 42})

    txn1.commit()
    txn2.simulate_failure()

    db.execute(txn1)
    db.execute(txn2)

Output

stdout
Transaction T1 committed with 2 operations
Transaction T2 failed before commit
Transaction T2 rolled back
Error: No operations to commit
Transaction T1 committed with 2 operations
Transaction T2 committed with 0 operations

How it works

This mock demonstrates the lifecycle of a distributed transaction: operations are added, then committed or rolled back as an atomic unit. The simulate_failure method triggers a rollback, mimicking a partial failure before commit. The FakeDatabase acts as a coordinator that attempts to execute each transaction, catching errors like empty operation lists. This pattern is useful for testing and debugging transaction logic without a real database. It shows how to enforce atomicity—either all operations succeed or none are applied.

Common mistakes

  • Forgetting to check if operations exist before commit
  • Not clearing operations on rollback, leaving stale state
  • Assuming all transactions follow the same commit path without failure handling
  • Mixing the mock with real database calls without abstraction

Variations

  1. Use a context manager to auto-commit or rollback on exception
  2. Implement a two-phase commit protocol with prepare and commit steps

Real-world use cases

  • Unit-testing service code that must handle partial failures without a real database.
  • Simulating retry and rollback logic in an orchestration layer before wiring up actual DB connections.
  • Teaching or demonstrating atomicity and failure semantics in microservices training materials.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Database scaling & optimization

Related tutorials and quizzes for this topic.