redhotvengeance
redhotvengeance

Reputation: 27866

Strong consistency within transactions in Google Cloud Datastore

Google Cloud Datastore is a non-relational database, and is built on the concept of eventual consistency. It also supplies a means to get strong consistency through ancestor queries and entity groups. However, I am not getting strong consistency when using ancestor queries within a transaction.

Consider this:

class Child(ndb.Model):

    @classmethod
    def create(cls):
        child = cls()
        child.put()
        print Child.query().fetch()

Child.create()

Since this did not use an entity group, it operates with eventual consistency. As expected, we get:

[]

Let's try it using entity groups and an ancestor query:

class Parent(ndb.Model):

    pass


class Child(ndb.Model):

    @classmethod
    def create(cls, parent):
        child = cls(parent=parent)
        child.put()
        print Child.query(ancestor=parent).fetch()


parent = Parent().put()
Child.create(parent)

Here we get strong consistency, so the output is:

[Child(key=Key('Parent', <id>, 'Child', <id>))]

However, when we throw a transaction into the mix:

class Parent(ndb.Model):

    pass


class Child(ndb.Model):

    @classmethod
    @ndb.transactional
    def create(cls, parent):
        child = cls(parent=parent)
        child.put()
        print Child.query(ancestor=parent).fetch()


parent = Parent().put()
Child.create(parent)

The output is:

[]

Given that translations are meant to primarily work with ancestor queries (the cross-group flag even exists just to get around that requirement), why is strong consistency being lost inside a transaction?

Upvotes: 5

Views: 1464

Answers (1)

minou
minou

Reputation: 16563

Google's docs here do address your last example:

Unlike with most databases, queries and gets inside a Cloud Datastore transaction do not see the results of previous writes inside that transaction. Specifically, if an entity is modified or deleted within a transaction, a query or get returns the original version of the entity as of the beginning of the transaction, or nothing if the entity did not exist then.

I can't explain this better than the Google docs do, but this is intended behavior for transactions based on how Google implements transaction isolation.

Upvotes: 4

Related Questions