-
Notifications
You must be signed in to change notification settings - Fork 68
NDB: Transactions #4
Description
Thinking out loud/brain dump, for transactions in NDB.
At the Datastore API level, a transaction is begun with a BeginTransaction call which returns a transaction id. By passing the transaction id back as a read option, read calls can present a consistent view of the database at the time the transaction was begun. Commit ends the transaction, by applying all of the mutations passed in with the CommitRequest. The Commit call is actually the only call which can change the database state, and can be called with or without a transaction. Because of this, when in a transaction, all changes to database state must be gathered into a single Commit call to end the transaction.
This explains why, in the high level documentation for Datastore, we read: "[The] consistent snapshot view also extends to reads after writes inside transactions. Unlike with most databases, queries and gets inside a Cloud Datastore transaction do not see the results of previous writes inside that transaction." The reason, of course, is that the writes haven't been sent to the back end yet—they're only sent at commit time.
The practical upshot for NDB is that if we're in a transaction, any writes need to gathered for the eventual call to Commit at the end of the transaction. For methods like Model._put(), which return the (possibly new) key for the written entity, we'll need to make calls to AllocateIds to prefetch new keys before committing.
Question: What did old NDB do, in terms of reads after writes in a transaction? Is it the same behavior as modern datastore, or did it show the writes in subsequent reads? Note, that there's possible interaction with one or both of the caching layers here. Since the semantics of caching in old NDB are not well understood yet, it's not obvious what the interaction might be.