只有一个实体的跨组事务错误

时间:2013-04-03 00:20:58

标签: google-app-engine

我正在尝试执行下面的代码。有时它工作正常。但有时它不起作用。

@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)

我收到了错误:

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

所以,我的问题是:

如果我只更改一个实体(models.Site),为什么我会收到跨群组交易错误?

4 个答案:

答案 0 :(得分:1)

跨群组交易错误是指使用的entity groups,而不是使用的类型(此处Site)。

当它发生时,这是因为您正在尝试对具有不同父项的实体进行交易,因此将它们放在不同的实体组中。

SHAMELESS PLUG:

您应该停止使用db并将代码移至ndb,尤其是因为您似乎处于开发阶段。

答案 1 :(得分:1)

如果在get_by_key_name()查询中指定parent = None,这是否有效?

基本上,为了使用事务,事务中的所有实体必须共享相同的父级(即,您使用一个父级进行查询,并使用同一父级创建新实体),或者必须使用XG事务。您看到了一个问题,因为您没有指定父级。

您可能需要创建人工实体以表现为父母,以便做您正在尝试做的事情。

答案 2 :(得分:1)

我有同样的问题。通过单步执行客户端代码,我做了以下两个观察:

1)设置(无)的父级似乎仍然表示该类型的父级,即使没有选择该父级的特定记录。
2)您的交易也将包括所有ReferenceProperty属性。

因此,理论上,如果您没有在任何影响的类型上声明父级(通过省略或设置为(None)),则应该获得跨组事务异常(如果至少有)两个(因为如果你使用A类和B类,看起来你正在使用两个不同的实体组,A记录和B记录), - 以及任何ReferenceProperty引用的任何类型属性。

要解决此问题,您必须至少创建一个没有任何属性的类,可以将其设置为所有先前无父记录的父级,以及它们声明的所有ReferenceProperty属性的父级。

如果这还不够,则设置跨群组交易的标志。

此外,对我来说,例外的文本是:“需要明确指定跨组事务”(复数“组”)。我有Python AppEngine客户端的1.7.6版本。

如果适合您的情况,请提供此答案。

答案 3 :(得分:1)

如日志中所述:“需要明确指定跨组事务”。 尝试使用

指定它
@db.transactional(xg=True)

而不是:

@db.transactional