Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine AppEngine实体建模-最小化实体组并实现原子级联更新/删除_Google App Engine_Jpa - Fatal编程技术网

Google app engine AppEngine实体建模-最小化实体组并实现原子级联更新/删除

Google app engine AppEngine实体建模-最小化实体组并实现原子级联更新/删除,google-app-engine,jpa,Google App Engine,Jpa,我正在学习AppEngine并开始开发新的应用程序,希望澄清一些事情 我明白 A.为了实现多个实体更新/删除的原子性,我们需要在一个事务中进行更新/删除,因此所有实体都应该属于同一个实体组 B拥有大型实体组是不可伸缩的,因为它会导致争用。 (Q1:对吗?) 为了便于讨论,这里有一个在线考试系统的实体模型: 实体: 主题 考试 页 问题: 答复 正如您从顶部看到的,每个实体1-多与最下面的一个实体的关系,即1个科目可以有许多考试,1个考试->许多页面,1个页面可以有许多问题 如您所见,我希望在这些

我正在学习AppEngine并开始开发新的应用程序,希望澄清一些事情

我明白 A.为了实现多个实体更新/删除的原子性,我们需要在一个事务中进行更新/删除,因此所有实体都应该属于同一个实体组 B拥有大型实体组是不可伸缩的,因为它会导致争用。 (Q1:对吗?)

为了便于讨论,这里有一个在线考试系统的实体模型:

实体: 主题 考试 页 问题: 答复

正如您从顶部看到的,每个实体1-多与最下面的一个实体的关系,即1个科目可以有许多考试,1个考试->许多页面,1个页面可以有许多问题

如您所见,我希望在这些实体之间建立级联更新/删除关系(JPA datanucleus appengine实现通过将所有实体置于同一实体组下(Q2:正确?)来支持这一点(隐藏),尽管appengine本机不支持此约束)所以很自然的,所有的都会归入同一个实体组,所以 A.我可以在事务中删除页面(如果我的用户删除了),并确保所有页面、问题和答案都已删除 B或者我可以在一个事务中删除一个主题,全部清除它下面的所有内容

因此,当我将其扩展到我的真实应用程序时,我发现我的所有(或至少大多数)实体都是相互关联的,并且适合于同一个实体组,以便能够一起处理它们——这使得我的模型效率低下

问题3:请就如何重新思考这个设计(以及最佳实践)并仍然实现我所需要的提供建议。如果需要,请多问我一些。 如果你能给我举一些相关的例子,那就太好了

p、 我能想到的s.1解决方案是将每个实体放在一个单独的实体组中,每个实体(比如考试)中有一个名为“is_DELETED”的单独持久字段,默认为FALSE(值0)。一旦用户删除了一个考试,我会将该字段设置为1(TRUE),并且不再加载它们。我将编写一个Cron作业,清除后端中单独事务中的所有相关实体,如果需要,将在失败时重试。但我确信这并不优雅,也不确定这是否会奏效

谢谢大家的回复,
Hari

改善事物的最简单方法之一就是首先减少实体。我真的想不出一个非常好的理由,为什么页面、问题和答案需要分开。我怀疑您通常会在同一个请求的一页上显示所有问题,没有例外。如果真是这样,就把它们放在一个实体中

使用检查实体作为页面的父对象确实很有意义;一方面,每次考试可能只限于合理的、少量的页面,因此扩大考试规模可能不会有多大影响

另一方面,每个科目可能有很多考试,因此,科目不应该出现在考试的祖先中(延伸到页数)

如果出于某种原因,您需要删除数学科目中的所有考试,即使它们在同一个实体组中,您可能无法在一个事务中完成整个删除,而不会超时。您甚至可能无法在单个请求中完成删除

这表明您应该为此操作使用任务队列。当主题发生级联更改时,请求处理程序需要插入一个新任务,然后成功返回。不要忘记只更新请求处理程序中的主题实体

任务队列从数据存储中提取受影响的实体块,更新它们,然后检查时间。如果还有更多的时间可以继续更新,它会拖出另一个实体块,以此类推,直到没有剩余的实体。如果时间快到了,任务只会将自己添加回队列,以便在重新启动时可以从停止的位置重新启动


最好将第一个任务安排在最初请求的未来几秒钟内,这样,例如,如果主题被删除,删除可以传播到未来的请求中,并且在任务开始时,该主题中没有新的考试可以创建。

但是,我仍然无法理解最后一段。也许我应该先学习任务队列?主要是“删除可以传播到未来的请求中,并且在任务开始时无法创建该科目的新考试。”这如何确保在后续请求中不能添加新考试?如果我理解正确,您的意思是任务将首先删除主题(单独)(然后慢慢删除所有考试),以便在将来的请求中,我可以确保由于主题不存在,无法通过检查(不)主题的存在来将考试添加到其下。如果任务队列无法删除某些实体,又该怎么办。我们可能需要通过重试手动处理?我问的原因是交易并没有让我们处于不一致的状态。所以,我只想确定这是以您建议的方式模拟的。再次感谢。“先删除科目(单独)(然后慢慢删除所有考试”正确!如果要删除的实体超过1000个,那么它肯定无法删除其中的一些实体,仅通过数据存储的fiat。唯一的处理方法是重试其余行。首先更新父项意味着将来对子项的所有更新都是一致的,并且只有旧的子项需要t的纠正操作问。在将来安排任务可以确保任务需要担心的所有更新都已经发生并通过数据存储传播,现在不再是争论的主题。谢谢你!顺便说一句,伙计们,还有其他建议/意见吗?