Reputation: 1738
I have what boils down to these helper methods on an ndb.Model
class:
@classmethod
@ndb.transactional(retries=2)
def new(cls, *args, **kwargs):
internal_name = kwargs['internal_name']
new_company = cls.get_or_insert(internal_name, **kwargs)
new_company.put()
return new_company
@classmethod
@ndb.transactional(retries=2)
def get(cls, internal_name):
result = cls.query(cls.internal_name == internal_name)
if result.count() != 1:
raise Exception("this is a problem");
return result.get()
I wrote a test to verify my assumptions:
def testCanCreateRetrieveCompany(self):
company = self.models.Company.new(internal_name="google", description="search engine")
reread_company = self.models.RichCompany.get("internal_name")
self.assertTrue(True)
However, this fails with the this is a problem
exception every time!
However, if I change the test to:
def testCanCreateRetrieveCompany(self):
company = self.models.Company.new(internal_name="google", description="search engine")
company.put()
reread_company = self.models.RichCompany.get("internal_name")
self.assertTrue(True)
this seems to pass. I have absolutely no idea why this passes when the first one doesn't. Also, removing the @ndb.transactional
operator seems to make this work. Except for I obviously want this to be transactional.
Not sure what's going on. I know there are caveats in the docs around reads in transactions (only ever see original read-state of transaction) but I wasn't aware there were any such caveats for writes. Does anyone have any insight?
Upvotes: 0
Views: 97
Reputation: 1738
So after a bit more digging, I think I'm just seeing that the darn updates might be transactional, but are still, in fact eventually consistent - that is, just because the method is transactional, doesn't mean the update made is going to be strongly consistent. I ended up adding a parent/ancestor component to the company keys (so all company objects share a single ancestor) and that gives me the effect I want. See:
ndb and consistency: Why is happening this behavior in a query without a parent
Upvotes: 1