在 App Engine 中使用实体组的良好开源示例?

发布于 2024-07-27 00:08:28 字数 1542 浏览 8 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝天 2024-08-03 00:08:28

实体组的主要用途是提供一种更新事务中多个实体的方法。

如果你还没有使用过它们,那就算算你的祝福吧。 要么您一直在设计数据模型,以便不需要同时更新两个实体才能保持一致,要么您确实需要它们,但您很幸运:)

想象一下我有一个发票实体类型和 LineItem 实体类型。 一张发票可以有多个与其关联的 LineItem。 我的发票实体有一个名为 LastUpdated 的字段。 每当将 LineItem 添加到我的发票时,我都希望将当前日期存储在 LastUpdated 字段中。

我的更新函数可能如下所示(伪代码)

invoice.lastUpdated = now()
lineitem = new lineitem()

invoice.put()
lineitem.put()

如果发票 put() 成功而 lineitem put() 失败,会发生什么? 我的发票日期将显示某些内容已更新,但实际更新(新的 LineItem)不会在那里。 解决方案是将两个 put() 都放在一个事务中。

另一种解决方案是使用查询来查找最后插入的 LineItem 的日期,而不是将此数据存储在 lastUpdated 字段中。 但是,每次您想知道上次添加订单项的时间时,这都需要获取发票和所有订单项,从而消耗宝贵的数据存储配额。

编辑以回复发帖者的评论

啊。 我想我理解你的困惑。 上述段落说明了交易为何如此重要。 但你说你仍然不关心实体组,因为你看不到它们与事务的关系。 但是,如果您正在使用 db.run-in-transaction,那么您正在使用实体组,也许您没有意识到这一点! 每笔交易都涉及一个且仅一个实体组,并且任何给定的交易只能影响属于同一组的实体。 请参阅此处

“一个中的所有数据存储操作
交易必须在实体上进行
在同一实体组中”。

您在事务中做了什么事情?有很多充分的理由只对一个实体使用事务,默认情况下该实体位于其自己的实体组中。但有时您需要保留 2 个或更多实体同步,就像上面的示例一样,如果 Invoice 和 LineItem 实体不在同一实体组中,那么您无法将对它们的修改包装在 db.run-in-transaction 调用中,因此您可以随时进行。要以事务方式对两个或多个实体进行操作,您需要首先确保它们位于同一组中,希望这可以更清楚地说明它们的用途。

The main use of entity groups is to provide the means to update more than one entity in a transaction.

If you haven't had to use them, count your blessings. Either you have been designing your data models such that no two entities ever need to be updated at the same time in order to remain consistent, or else you do need them but you've gotten lucky :)

Imagine that I have an Invoice entity type, and a LineItem entity type. One Invoice can have multiple LineItems associated with it. My Invoice entity has a field called LastUpdated. Any time a LineItem gets added to my Invoice, I want to store the current date in the LastUpdated field.

My update function might look like this (pseudocode)

invoice.lastUpdated = now()
lineitem = new lineitem()

invoice.put()
lineitem.put()

What happens if the invoice put() succeeds and the lineitem put() fails? My invoice date will show that something was updated, but the actual update (the new LineItem) wouldn't be there. The solution is to put both puts() inside a transaction.

An alternative solution would be to use a query to find the date of the last inserted LineItem, instead of storing this data in the lastUpdated field. But that would involve fetching both the Invoice and all the LineItems every time you wanted to know the last time a lineitem was added, costing you precious datastore quota.

EDIT TO RESPOND TO POSTER's COMMENTS

Ah. I think I understand your confusion. The above paragraphs establish why transactions are important. But you say you still don't care about Entity groups, because you don't see how they relate to transactions. But if you are using db.run-in-transaction, then you are using entity groups, perhaps without realizing it! Every transaction involves one and only one entity group, and any given transaction can only affect entities belonging to the same group. see here

"All datastore operations in a
transaction must operate on entities
in the same entity group".

What kind of stuff are you doing in your transactions? There are plenty of good reasons to use transactions with just one Entity, which by default is in its own Entity Group. But sometimes you need to keep 2 or more entities in sync, like in my example above. If the Invoice and the LineItem Entities are not in the same entity group, then you could not wrap the modifications to them in a db.run-in-transaction call. So anytime you want to operate on 2 or more entities transactionally you need to first make sure they are in the same group. Hope that makes it more clear why they are useful.

往昔成烟 2024-08-03 00:08:28

我在此处使用过它们。 我将我的客户对象设置为地图标记的父对象。 这为每个客户创建了一个实体组,并给了我两个优点:

  1. 获取客户的标记要快得多,因为它们与客户对象物理存储在一起。(在同一服务器上,可能在同一磁盘上)

  2. 我可以在交易。 我怀疑事务要求它们操作的所有对象位于同一组中的原因是因为它们存储在同一物理位置,这使得更容易实现数据锁定。

I've used them here. I'm setting my customer object as the parent of the map markers. This creates an entity group for each customer and gives me two advantages:

  1. Getting the markers of a customer is much faster, because they're stored physically with the customer object.(On the same server, probably on the same disk)

  2. I can change the markers for a customer in a transaction. I suspect the reason transactions require all objects that they operate on to be in the same group is because they're stored in the same physical location, which makes it easier to implement a lock on the data.

人间☆小暴躁 2024-08-03 00:08:28

我在这里使用过它们 在这个简单的维基系统中。 页面的最新版本始终是根实体,过去的版本将最新版本作为祖先。 复制操作在事务中完成,以保持版本一致性,避免并发时丢失版本。

I've used them here in this simple wiki system. The latest version of a page is always a root entity and past versions have the latest version as ancestor. The copy operation is done in a transaction to keep the version consistency and avoid losing a version in case of concurrency.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文