只有一个实体的跨组交易错误

问题描述 投票:0回答:4

我正在尝试执行下面的代码。有时效果很好。但有时却不起作用。

@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
) 为什么我会收到跨组事务错误?

google-app-engine
4个回答
3
投票

日志中提到:“跨组交易需要明确指定”。 尝试使用

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

代替:

@db.transactional

1
投票

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

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

您可能需要创建人造实体来充当父母,以便做您想做的事情。


1
投票

跨组交易错误是指正在使用的实体组,而不是所使用的类型(此处为

Site
)。

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

无耻插头:

您应该停止使用

db
并将代码移至
ndb
,特别是因为您似乎处于开发阶段。


1
投票

我也有同样的问题。通过单步调试客户端代码,我得到了以下两个观察结果:

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

因此,理论上,如果您没有在您所影响的任何类型上声明父级(通过省略或设置为(无)),并且至少有两个(因为如果您使用类型 A 和类型 B,则看起来您正在使用两个不同的实体组(A 记录和 B 记录),以及任何 ReferenceProperty 属性引用的任何类型。

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.