Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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 ndb事务中的数据存储实体读取(仅限于密钥)_Google App Engine_Google Cloud Platform_Google Cloud Datastore_App Engine Ndb - Fatal编程技术网

Google app engine ndb事务中的数据存储实体读取(仅限于密钥)

Google app engine ndb事务中的数据存储实体读取(仅限于密钥),google-app-engine,google-cloud-platform,google-cloud-datastore,app-engine-ndb,Google App Engine,Google Cloud Platform,Google Cloud Datastore,App Engine Ndb,我有一个关于ndb事务中的数据存储实体读取的问题 我知道,当我们在ndb事务中读取一个实体时,该特定实体会被锁定,并且没有其他线程可以放置/更新/写入相同的实体,因为这将导致争用错误。 这完全有道理 然而,当我们只读取一个实体的键而不是事务中整个实体本身时会发生什么?这可以通过在ndb.query().fetch()中将keys_only标志传递为True来实现 在这种情况下,实体是否会再次被锁定?显示: 读写事务使用读写器锁来强制隔离和序列化 而且它没有提到任何在交易过程中仅使用键的具体情况。

我有一个关于ndb事务中的数据存储实体读取的问题

我知道,当我们在ndb事务中读取一个实体时,该特定实体会被锁定,并且没有其他线程可以放置/更新/写入相同的实体,因为这将导致争用错误。 这完全有道理

然而,当我们只读取一个实体的键而不是事务中整个实体本身时会发生什么?这可以通过在ndb.query().fetch()中将keys_only标志传递为True来实现 在这种情况下,实体是否会再次被锁定?

显示:

读写事务使用读写器锁来强制隔离和序列化

而且它没有提到任何在交易过程中仅使用
键的具体情况。所以我假设同样的情况适用于这种情况,如果你认为你仍然在做一个阅读,那么你就忽略了数据。
也就是说,也许这是可以改进到数据存储中的东西,甚至可以在文档中明确说明。如果你愿意,你可以考虑打开一个谷歌的特征请求来实现这一点。
读写事务使用读写器锁来强制隔离和序列化

而且它没有提到任何在交易过程中仅使用
键的具体情况。所以我假设同样的情况适用于这种情况,如果你认为你仍然在做一个阅读,那么你就忽略了数据。

也就是说,也许这是可以改进到数据存储中的东西,甚至可以在文档中明确说明。如果你愿意,你可以考虑打开一个谷歌的特性请求来实现这一点。

一般来说,最好是考虑它们的保证-可串行化的事务——而不是它们的实现细节——在这种情况下,读/写锁。实现细节(查询的执行方式、锁定粒度、锁定的确切内容等)可能随时发生变化,而保证不会发生变化

对于这个特定的问题,假设Firestore在数据存储模式下的当前实现:为了确保可序列化性,事务T1中的仅键查询锁定查询检查的索引项范围。如果这样的查询返回了实体E的密钥K,那么在不同事务T2中删除E的尝试必须删除E的所有索引项,包括查询锁定范围内的索引项。因此,在本例中,T1和T2需要相同的锁,两个事务中的一个将被延迟或中止

请注意,T2与T1有其他冲突的方式:它还可以创建一个与T1的查询匹配的新实体(这需要在T1的查询锁定的范围内写入一个索引项)


最后,如果T2更新(而不是删除)E的方式需要对T1查询检查范围内的索引项进行任何更新(例如,如果查询类似于“从X选择*其中a=5”,并且对E的更新不会更改其“a”属性的值),则T1和T2不会冲突(这是一种优化-如果这两个事务发生冲突,行为仍然是正确的,事实上,对于“数据存储本机”数据库,它们可能会发生冲突).

一般来说,最好从事务的保证(可序列化性)而不是实现细节(在本例中是读/写锁)来考虑事务。实现细节(查询的执行方式、锁定粒度、锁定的确切内容等)可以随时更改,但担保不会更改

对于这个特定问题,并假设Firestore当前在数据存储模式下的实现:为了确保可序列化性,事务T1中的仅键查询会锁定查询检查的索引项范围。如果这样的查询为实体E返回了键K,则在不同事务T2中删除E的尝试必须删除所有这些项E的索引项,包括查询锁定范围内的索引项。因此,在本例中,T1和T2需要相同的锁,并且两个事务中的一个将被延迟或中止

请注意,T2与T1有其他冲突的方式:它还可以创建一个与T1的查询匹配的新实体(这需要在T1的查询锁定的范围内写入一个索引项)

最后,如果T2更新(而不是删除)E的方式需要对T1查询检查范围内的索引项进行任何更新(例如,如果查询类似于“从X选择*其中a=5”,并且对E的更新不会更改其“a”属性的值),则T1和T2不会冲突(这是一种优化——如果这两个事务发生冲突,行为仍然是正确的,事实上,对于“数据存储本机”数据库,它们可能会发生冲突)