요청한 페이지는 현재 사용 중인 언어로 제공되지 않습니다. 페이지 하단에서 다른 언어를 선택하거나 Chrome에서 기본 제공되는 번역 기능을 사용해 웹페이지를 원하는 언어로 바로 번역할 수 있습니다.

Entity Group Version Workaround

At Google Cloud Next '18, we announced that all Cloud Datastore users will be automatically upgraded to Cloud Firestore in Datastore mode once Cloud Firestore becomes generally available. 

The upgrade to the Cloud Firestore storage engine brings the following benefits: 

  • Entity groups are no longer restricted to 1 transaction/second
  • Transactions are no longer limited to 25 entity-groups
  • All queries, not just ancestor queries, are strongly consistent

With the removal of the 1 transaction/second restriction, however, the entity group is no longer a unit of consistency.

When you request an entity group version, Cloud Firestore returns a monotonically increasing number. This number is guaranteed to increase on new writes to the entity group, but it also increases independently of user updates to the entity group. In Cloud Datastore, the entity group version changed only on writes to the entity group.

This new behavior might affect functionality that depends on the current behavior. For example, this would affect application logic like caching that depends on the entity group version updating only on new writes.

As a workaround, you can maintain the current behavior by keeping track of the entity group version manually. Whenever a change is made to entities in a group whose version needs to be tracked, increment a property of a specially designated entity. 

Java

For example, take this code to modify an entity:

Entity foo = …;
foo.setProperty("bar", "new_value");
datastore.put(foo);

Previously, you would use com.google.appengine.api.datastore.Entities to access the entity group version:

Key egKey = Entities.createEntityGroupKey(foo.getKey());
long version = Entities.getVersionProperty(datastore.get(egKey));

To maintain the behavior where the entity group version increases only with user updates, make an extra call to keep track of the entity group version and wrap the code in a transaction:

Entity foo = …;
foo.setProperty("bar", "new_value");
datastore.put(transaction, foo);
 
Entity groupVersion = loadOrCreateGroupVersion(foo);
groupVersion.setProperty("version", 
  (long) groupVersion.getProperty("version") + 1);
datastore.put(transaction, groupVersion);

This code uses the following helper method:

public static Entity loadOrCreateGroupVersion(Entity entity) {
  Key rootKey = entity.getKey();
  while (rootKey.getParent() != null) rootKey = rootKey.getParent();
 
  Key key = KeyFactory.createKey(rootKey,
                                 "EntityGroupVersion",
                                 "EntityGroupVersionKey");
 
  DatastoreService datastore = DatastoreServiceFactory
                               .getDatastoreService();
  Entity version;
  try {
    version = datastore.get(key);
  } catch (EntityNotFoundException e) {
    version = new Entity(key);
    version.setProperty("version", 0);
    datastore.put(version);
  }
 
  return version;
}

You can then retrieve the entity group version as follows:

Entity groupVersion = loadOrCreateGroupVersion(foo);
long version = groupVersion.getProperty("version");

 

Python (db)

For example, take this code to modify an entity:

def change_foo(key):

  foo = db.get(key)
  foo.bar = 'new_value'
  foo.put()

Previously, you would use db.metadata.get_entity_group_version() to access the entity group version:

db.metadata.get_entity_group_version(foo)

To maintain the behavior where the entity group version increases only with user updates, make an extra call to keep track of the entity group version and wrap the code in a transaction:

@db.transactional()
def change_foo(key):
  foo = db.get(key)
  foo.bar = 'new_value'
  foo.put()
  EntityGroupVersion.increase_version(foo)

This code uses the following helper method:

class EntityGroupVersion(db.Model):
  version = db.IntegerProperty()
 
  @staticmethod
  def increase_version(entity):
    entity_group_version = EntityGroupVersion.__load(entity)
    entity_group_version.version += 1
    entity_group_version.put()
 
  @staticmethod
  def get_version(entity):
    return EntityGroupVersion.__load(entity).version
 
  @staticmethod
  def __load(entity):
    root_key = entity.key()
    while root_key.parent():
      root_key = root_key.parent()
    key = db.Key.from_path('EntityGroupVersion',
                           'EntityGroupVersionKey',
                           parent=root_key)
    entity_group_version = db.get(key)
    if entity_group_version is None:
      entity_group_version = EntityGroupVersion(
          parent=root_key,
          key_name='EntityGroupVersionKey',
          version=1)
      entity_group_version.put()
    return entity_group_version

You can then retrieve the entity group version as follows:

version = EntityGroupVersion.get_version(foo)

Python (ndb)

For example, take this code to modify an entity:

def change_foo(key):
  foo = key.get()
  foo.bar = 'new_value'
  foo.put()

Previously, you would use ndb.metadata.get_entity_group_version() to access the entity group version:

ndb.metadata.get_entity_group_version(foo)

To maintain the behavior where the entity group version increases only with user updates, make an extra call to keep track of the entity group version and wrap the code in a transaction:

@ndb.transactional()
def change_foo(key):
  foo = key.get()
  foo.bar = 'new_value'
  foo.put()
  EntityGroupVersion.increase_version(foo)

This code uses the following helper method:

class EntityGroupVersion(ndb.Model):
  version = ndb.IntegerProperty()
 
  @staticmethod
  def increase_version(entity):
    entity_group_version = EntityGroupVersion.__load(entity)
    entity_group_version.version += 1
    entity_group_version.put()
 
  @staticmethod
  def get_version(entity):
    return EntityGroupVersion.__load(entity).version
 
  @staticmethod
  def __load(entity):
    entity_group_version = EntityGroupVersion.get_by_id(
        'EntityGroupVersionKey', parent=entity.key().root())
    if entity_group_version is None:
      entity_group_version = EntityGroupVersion(
          parent=entity.key().root(),
          id='EntityGroupVersionKey',
          version=1)
      entity_group_version.put()
    return entity_group_version

You can then retrieve the entity group version as follows:

version = EntityGroupVersion.get_version(foo)

도움이 되었나요?

어떻게 하면 개선할 수 있을까요?
false
Search
Clear search
Close search
Main menu
9435494648281269986
true
도움말 센터 검색
true
true
true
true
true
95384
false
false