这些天我在做很多实验,我想做的一件事就是结合两个流行的 NoSQL 数据库,即 Neo4j 和 MongoDB。仅仅因为我觉得它们完美地互补。Neo4j 中的一等公民,即关系,正是 MongoDB 中缺少的东西,而 MongoDb 允许我不在我的节点属性中放置大量数据。
所以我试图将两者结合在一个 Java 应用程序中,使用 Neo4j Java REST 绑定和 MongoDB Java 驱动程序。我所有的域实体都有一个唯一标识符,我将其存储在两个数据库中。其他数据存储在 MongoDB 中,实体之间的关系存储在 Neo4J 中。例如,两个数据库都包含用户 ID,MongoDB 包含个人资料信息,Neo4J 包含友谊关系。使用我编写的自定义数据访问层,这完全符合我的要求。而且速度很快。
但是......当我想创建一个用户时,我需要在 Neo4j 中创建一个节点和在 MongoDB 中创建一个文档。不一定是问题,除了 Neo4j 是事务性的而 MongoDB 不是。如果两者都是事务性的,我会在其中一个事务失败时回滚这两个事务。但由于 MongoDB 不是事务性的,我不能这样做。
我如何确保每当我创建用户时,要么同时创建节点和文档,要么两者都不创建。我不想最终得到一堆没有匹配节点的文档。
最重要的是,我不仅希望我的组合数据库交互符合 ACID,还希望它是线程安全的。GraphDatabaseService 和 MongoClient / DB 都是由单例提供的。
我发现了一些关于在 MongoDB 中创建“事务文档”的内容,但我真的不喜欢这种方法。我想要一些漂亮干净的东西,比如 neo4j beginTx、tx.success、tx.failure、tx.finish 设置。理想情况下,我可以在同一个 try/catch/finally 块中实现一些东西。
我是否应该切换到 CouchDB,这似乎是事务性的?
编辑:经过更多的研究,由评论引发,我开始意识到 CouchDB 也不适合我的特定需求。澄清一下,Neo4j 部分是一成不变的。Document Store 数据库只要有 Java 库就行。