@
c 这样就不得不多占用存储空间了。而且正如前面所说,假如你的实体生成以后,突然发现slug里有错别字,不得不更改,你就只能删掉重新创建一个实体了。而如果这个实体还是根实体的话,整个实体组可能都得重新创建。
@
darasion 在构造实体(准确来说是它的key)时可以指定一个实体为它的父实体。而且这个实体也可以作为其他实体的父实体。
由于一个实体最多只能有1个父实体(但是可以有多个子实体),所以一直向上总能找到一个没有父实体的实体,它就是这个实体组的根实体。
在单个事务中,你只能更改1个实体组里面的实体。
举例来说,如果把Reply的父实体定为Topic的话,用户在post一个reply时,就能在事务中完成创建Reply实体并将它的父实体Topic的reply字段加1。
而如果它们不在一个实体组,你就只能先put一个Reply实体,然后再找到对应的Topic实体,再给它的reply+1。而如果你Reply实体put成功,Topic实体put失败,那么就存在不一致了。
Google给出的方式是分离事务,也就是用一个task来执行Topic的保存,因为task在失败时会自动重试,直到成功。
更常见的例子,如果不使用事务的可能造成这种情况:
1.一个用户a的访问使得你得给Topic的hit加1,于是你取出了这个topic。
2.同时,另一个用户b也要编辑这个Topic的content字段,于是也取出了这个topic
3.b编辑完了,保存成功。
4.a的hit += 1执行完了,也进行保存,但是这个topic的content字段是a取出来时的内容,于是这次保存就让b的编辑无效了。
而单个实体本身就是一个实体组,因此自然可以使用事务,它就可以保证2个人取出数据到保存成功这个过程是串行的,相互之间不会覆盖。