Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strong consistency within transactions in Google Cloud Datastore

Tags:

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?

like image 295
redhotvengeance Avatar asked Feb 18 '17 19:02

redhotvengeance


1 Answers

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.

like image 161
gaefan Avatar answered Sep 22 '22 10:09

gaefan