İçeriğe geç
Community

KONULARI KEŞFET

Editoryal yaklaşım

CoreTrailKit ile yeni mi tanışıyorsun?

Servislerini izle. Kanıtları elinin altında tut.

CoreTrailKit
Yazılara dön
REHBER/ Google Cloud

Firestore: read before writing in a transaction

A Firestore transaction queues a document update and then tries to read another value. The Python client raises ReadAfterWriteError because transaction reads must precede writes.

Yazar: CoreTrailKit3 dk okuma

01

Locate the first queued write

Inspect the transaction callback and any helpers it calls. A helper that queues a set or update can make a later read invalid even if those operations are separated by several layers of application code.

Our incorrect callback queued a value and then called DocumentReference.get with the same transaction. The SDK raised ReadAfterWriteError before a document-read request or commit reached the fixture. The rejection occurred in the transaction API contract, not in a database query result.

02

Gather the required reads first

List the documents and values needed for the decision and read them before adding any writes. Reads in a transaction should not be used to inspect the result of a write you just queued. Calculate the proposed value in memory instead.

For a real operation, validate existence, types, and domain limits on those snapshots. The fixed example below expects an existing counter with an integer value; it intentionally raises if that prerequisite is not satisfied.

03

Compute and queue the change in one callback

The callback returns the computed value while queuing the update through the supplied transaction. It does not issue an unrelated read after that update. The caller invokes it through the SDK’s transactional decorator.

Use an appropriately authorized client and document reference in your application. Running the final call below writes the selected counter if the transaction commits; it is not a read-only inspection command.

python · ÖRNEK
from google.cloud import firestore

@firestore.transactional
def increment_counter(transaction, reference):
    snapshot = reference.get(transaction=transaction)
    if not snapshot.exists:
        raise ValueError("Counter is missing")
    current = snapshot.get("value")
    if not isinstance(current, int) or isinstance(current, bool):
        raise ValueError("Counter value must be an integer")
    updated = current + 1
    transaction.update(reference, {"value": updated})
    return updated

# Authorized write when deliberately invoked:
# updated = increment_counter(db.transaction(), counter_reference)

04

Keep retryable callbacks free of external side effects

The service can cause a transaction callback to run again under contention. Sending an email or making a payment inside the callback can repeat an effect even though document changes are committed atomically.

Choose an application design that records the necessary intent atomically and handles external work with an appropriate idempotent process. Moving a side effect into a transaction callback does not make that external system part of the Firestore transaction.

05

Verify ordering and the final state

The corrected local callback read a fixture value of one and submitted an update to two in one commit. The checks observed the real SDK’s read and commit calls, while the stub supplied deterministic document and transaction responses.

For production verification, use an approved test document and confirm the final state after the transaction completes. Add separate contention and failure tests when those guarantees matter. A local stub cannot prove that a live service handles concurrent writers, rules, or retries as your application requires.

Sınırları bil

Reproduced with google-cloud-firestore 2.34.1 against a deterministic local gRPC contract fixture. The actual SDK rejected the read-after-write before a read or commit; the reordered callback read once and committed the computed value. No real Firestore isolation, contention, retry conflict, or IAM behavior was tested.

Kaynaklar ve ileri okuma

CoreTrailKit tarafından hazırlanan teknik yayın.

Bütün yazıları keşfet

KEŞFETMEYE DEVAM ET