ndb.put_multi是否具备原子性?批量写入异常场景行为咨询
关于ndb.put_multi的原子性与部分无效实体的行为解答
问题1:ndb.put_multi是否具备原子性?
直白点说:默认情况下不具备跨实体的原子性。
原子性的核心是“要么全部成功,要么全部失败”,但ndb.put_multi默认的执行逻辑是逐个处理传入的实体,每个实体的写入操作是独立提交的。这意味着如果中间某个实体写入失败,之前已经成功写入的实体依然会保留在数据存储中,不会回滚。
如果需要实现原子性的批量写入,你得把ndb.put_multi包裹在事务里,但这里有个硬限制:事务内的所有实体必须属于同一个实体组。要是实体分属不同的实体组,事务会直接报错,根本执行不了。这种情况下,事务就能保证要么所有实体都写入成功,要么全部失败,不会有部分数据残留。
问题2:一批待写入实体中有一个无效,调用ndb.put_multi时的行为?
这得分两种场景来看:
- 非事务环境下:
ndb.put_multi会挨个尝试写入实体。在碰到那个无效实体之前,所有有效的实体都会被成功写入并持久化;当处理到无效实体时,操作会抛出对应的异常(比如验证错误、违反数据约束等),而且后面的实体不会再被尝试写入。最终结果就是部分数据已写入,无效实体及之后的都没写入。 - 事务环境下(且所有实体同属一个实体组):整个批量写入操作是原子的。只要有任何一个实体无效,整个事务就会回滚,所有实体都不会被写入,同时抛出异常。
举个简单例子:假设你有5个实体,第3个是无效的。非事务场景下,前2个会成功写入,第3个触发错误,第4、5个不会被处理;事务场景下,5个实体都不会被写入,回到初始状态。
内容的提问来源于stack exchange,提问作者Shahzaib Ali
相关产品推荐
相关产品推荐

