Skip to content

Transaction Reference

Transaction management and concurrency control for the Google Cloud Datastore ODM.

This module provides context managers and decorators to orchestrate ACID-compliant transactions. It utilizes Python contextvars to automatically route all ODM model operations (like .get(), .put(), and queries) through the active transaction without requiring developers to manually pass connection objects.

transaction(project=None, database=None)

A context manager that scopes a Datastore transaction.

When entered, this context manager requests a transaction ID from the Datastore backend. Any ODM .get(), .put(), .delete(), or .query() operations executed inside the with block will automatically bind to this transaction.

⚠️ Snapshot Isolation Rule (Read-Before-Write): Datastore transactions use Snapshot Isolation. When the transaction opens, it freezes the database state. If you .put() an entity inside the block, it is only buffered locally in memory. A subsequent .query() or .get() inside the same block will not see the uncommitted entity. Always perform all reads before performing any writes.

Parameters:

Name Type Description Default
project str | None

The specific GCP project to run the transaction against. If omitted, defaults to the environment configuration.

None
database str | None

The specific Datastore database to run the transaction against.

None

Yields:

Name Type Description
Transaction Transaction

The raw Datastore transaction object, in case manual SDK bypass is needed.

Raises:

Type Description
RuntimeError

If called from within an already active transaction (nested transactions are strictly prohibited by Google Cloud Datastore).

Examples:

Safe Read-Modify-Write pattern:

with transaction():
    # 1. Read from the snapshot
    alice = Account.get(alice_key)
    bob = Account.get(bob_key)

    # 2. Modify memory state
    alice.balance -= 50
    bob.balance += 50

    # 3. Buffer mutations for commit
    Account.put_multi([alice, bob])

transactional(retries=3, project=None, database=None)

Decorator that wraps a function in a Datastore transaction with automatic retries.

Because Datastore utilizes Optimistic Concurrency, transactions do not lock rows. Instead, if another process modifies your entities while your transaction is open, your commit will fail and raise an Aborted exception.

This decorator catches Aborted exceptions, applies an exponential backoff sleep (with jitter), and re-executes the function automatically.

Parameters:

Name Type Description Default
retries int

The maximum number of retry attempts before giving up and raising the Aborted exception to the caller. Defaults to 3.

3
project str | None

The specific GCP project override.

None
database str | None

The specific Datastore database override.

None

Returns:

Name Type Description
Callable Callable

The decorated function.

Raises:

Type Description
ValueError

If the retries count is less than 0.

TypeError

If the decorated function is a generator (yielding from inside a transaction causes dangling database locks).

Aborted

If all retry attempts are exhausted.