【问题标题】:GAE asks for XG transaction on root entityGAE 要求在根实体上进行 XG 交易
【发布时间】:2014-01-26 15:31:54
【问题描述】:

我正在尝试使用以下代码添加一个新的根实体:

    try {
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        Key eventKey = datastore.allocateIds("Event", 1).getStart();
        String keyString = KeyFactory.keyToString(eventKey);

        //TransactionOptions options = TransactionOptions.Builder.withXG(true);
        Transaction txn = datastore.beginTransaction();
        Entity eventEntity = new Entity("Event", keyString);

        datastore.put(eventEntity);

        txn.commit();
    } catch (Exception e) {
        log.log(Level.SEVERE, e.getMessage(), e);
        throw new InternalServerErrorException(e);
    }

这是一个简单的事务性数据存储插入,根据documents 假设可以工作 -

每个根实体都属于一个单独的实体组,因此单个事务不能创建或操作多个根实体,除非它是 XG 事务

我的“事件”实体没有任何祖先而且我只在事务中处理它。但由于某种原因,我得到以下异常:

java.lang.IllegalArgumentException: 跨组事务需要显式指定,参见 TransactionOptions.Builder.withXGfound 两个 Element { 类型:“事件” 编号:4 } 和元素{ 类型:“事件” 名称:“ahBldmVudHNmaW5kZXIyMDEzcgsLEgVFdmVudBgEDA” }

知道这里有什么问题吗?

【问题讨论】:

    标签: java google-app-engine transactions


    【解决方案1】:

    您的代码对我有用。我将它粘贴到一个正在运行的简单应用程序的中间,运行它两次,它创建了两个“事件”实体并且没有抛出任何异常。您的应用程序在其他地方有问题。

    【讨论】:

    • 实际上在事务中,我在实体上设置了更简单的属性,并将文档添加到 2 个搜索 API 索引。而已。这应该有什么不同吗?
    • 忘记我的最后评论。它没有(产生影响),因为异常发生在 datastore.put(eventEntity);行和我只在那之后做搜索 API 的东西。可能是因为我的一些 Event 实体是在没有使用 allocateIds 方法的情况下添加的吗?
    • 更多属性没有区别,正如您所确认的,并且 allocateIds 与键唯一性有关,而不是实体组。更可能的罪魁祸首是在不同实体种类上的未提交事务。
    【解决方案2】:

    好的,问题是因为我在事务中调用了以下方法:

    private boolean containsEvent(Key eventKey) {
        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
        boolean contains = true;
        try {
            if (eventKey == null) {
                return false;
            }
    
            Entity eventEntity = datastore.get(eventKey);
            if (eventEntity == null) {
                contains = false;
            }
        } catch (com.google.appengine.api.datastore.EntityNotFoundException e) {
            contains = false;
        }
        return contains;
    }
    

    此代码仅检查此实体是否已存在于数据存储区中。
    显然,因为该实体尚未提交,这被视为获取不同的根实体,因此使其成为 XG 操作。一旦我将此方法调用移到事务之外,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多