MongoDB 引用原子 insert/delete
MongoDB ref atomic insert/delete
我有一个案例,我有一个文档 A 引用了一个文档 B。
这意味着为了引用/删除新创建的文档 B,我有两个选择:
- 在文档 A 中嵌入文档 B
- 让应用代码先创建文档B,再更新文档A
我知道MongoDB/Morphia不支持对引用的原子操作所以你必须自己管理它。
对于我的用例,嵌入文档 B 不是一个选项,它们是独立集合的一部分,应该保持原样。
所以我只剩下选项 2。但我想知道管理请求的事务性质的最佳解决方案是什么。
IE。如果文档 B 是 inserted/deleted 但对文档 A 的引用 creation/deletion 失败,则不应提交。
您是否通过在 try/catch/finally 块中反转操作来回滚?
这个问题有通用的解决方案吗?
我用Morphia来道。
你最好的选择可能是做这样的事情:
datastore.save(b);
try {
datastore.save(a);
} catch (Exception e) {
datastore.delete(b);
}
当然,你可以在尝试中同时进行两次保存。这并不能保护您免受保存之间的灾难性应用程序崩溃,但在其他方面已经足够好了。数据库中还有竞争条件需要考虑(例如,并发插入具有唯一索引的字段具有相同值的文档)。
我有一个案例,我有一个文档 A 引用了一个文档 B。
这意味着为了引用/删除新创建的文档 B,我有两个选择:
- 在文档 A 中嵌入文档 B
- 让应用代码先创建文档B,再更新文档A
我知道MongoDB/Morphia不支持对引用的原子操作所以你必须自己管理它。
对于我的用例,嵌入文档 B 不是一个选项,它们是独立集合的一部分,应该保持原样。
所以我只剩下选项 2。但我想知道管理请求的事务性质的最佳解决方案是什么。
IE。如果文档 B 是 inserted/deleted 但对文档 A 的引用 creation/deletion 失败,则不应提交。
您是否通过在 try/catch/finally 块中反转操作来回滚?
这个问题有通用的解决方案吗?
我用Morphia来道。
你最好的选择可能是做这样的事情:
datastore.save(b);
try {
datastore.save(a);
} catch (Exception e) {
datastore.delete(b);
}
当然,你可以在尝试中同时进行两次保存。这并不能保护您免受保存之间的灾难性应用程序崩溃,但在其他方面已经足够好了。数据库中还有竞争条件需要考虑(例如,并发插入具有唯一索引的字段具有相同值的文档)。