Search code examples
google-app-engine

cross-group transaction error with only one entity


I'm trying to execute the code below. Some times it works fine. But some times it does not work.

@db.transactional
def _add_data_to_site(self, key):
    site = models.Site.get_by_key_name('s:%s' % self.site_id)
    if not site:
        site = models.Site()

    if key not in site.data:
        site.data.append(key)
        site.put()
        memcache.delete_multi(['', ':0', ':1'], key_prefix='s%s' %                                                                       
            self.site_id)

I'm getting the error:

File "/base/data/home/apps/xxxxxxx/1-7-1.366398694339889874xxxxxxx.py", line 91, in _add_data_to_site
  site.put()
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1070, in put
  return datastore.Put(self._entity, **kwargs)
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore.py", line 579, in Put
  return PutAsync(entities, **kwargs).get_result()
File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 604, in get_result
  return self.__get_result_hook(self)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1569, in __put_hook
  self.check_rpc_success(rpc)
File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1224, in check_rpc_success
  raise _ToDatastoreError(err)
BadRequestError: cross-group transaction need to be explicitly specified, see TransactionOptions.Builder.withXG

So, my question is:

If I'm changing only one entity (models.Site) why am I getting a cross-group transaction error?


Solution

  • Does this work if you specify parent=None in your get_by_key_name() query?

    Essentially, in order to use a transaction, all entities in the transaction must share the same parent (ie you query using one parent, and create a new entity withe the same parent), or you must use a XG transaction. You're seeing a problem because you didn't specify a parent.

    You may need to create artificial entities to behave as parents in order to do what you're trying to do.