在Java中测试MongoDB:并发问题
我正在测试Java应用程序中将数据存储在MongoDB数据库中的部分。我的测试设置如下所示:在Java中测试MongoDB:并发问题,java,mongodb,concurrency,jenkins,Java,Mongodb,Concurrency,Jenkins,我正在测试Java应用程序中将数据存储在MongoDB数据库中的部分。我的测试设置如下所示: public class MongoDataStoreTest { private MongoClient client; @Before public void before() throws UnknownHostException { this.client = new MongoClient(); } @After publi
public class MongoDataStoreTest {
private MongoClient client;
@Before
public void before() throws UnknownHostException {
this.client = new MongoClient();
}
@After
public void after() throws InterruptedException {
this.client.dropDatabase("testdb");
this.client.close();
}
}
public void clearData() {
try {
for (String collection : datastore.getDB().getCollectionNames()) {
// We must not mess with system indexes and users as this will cause
// errors
if (!collection.startsWith("system.")) {
// Do not drop the entire database or full collections as this
// will lead to missing index errors (for no obvious reason).
datastore.getDB().getCollection(collection).drop();
}
}
} catch (MongoException e) {
LOG.log(Level.INFO,
"Could not fetch all collection names - this is a permission thing, but can be ignored");
}
// The indexes are not automatically recreated (for no obvious
// reason) - ensure they are still there after the drop().
datastore.ensureIndexes();
datastore.ensureCaps();
}
在我的测试中,我执行了以下代码:
DB database=client.getDB(“testdb”)
database.getCollection(“testcoll”)
collection.insert(object,WriteConcern.SAFE)
从我的测试设置代码中可以看出,在每次测试之后,我都会删除数据库并关闭所有客户端连接。我做了十次这样的测试。在本地运行它们时,一切都按照我的预期进行。每次测试都会插入对象,然后删除数据库(我可以在mongo日志中看到这一点)。但是,当在Jenkins服务器上执行此操作时,有时会发生这样的情况:当查询数据库时,上一个测试的对象仍在该数据库中,尽管该数据库本应被删除。对我来说,这看起来像是一个并发问题,但我看不出竞争条件位于何处。我无法访问Jenkins服务器上的数据库日志。有人知道我应该改变什么以确保我的测试总是成功吗?不要删除数据库。mongo中可能有一些内部引用。我不相信,您的测试用例需要删除DB。通常只需删除测试集合中的所有文档就足够了问题是由dropDatabase操作引起的。 在Jenkins服务器上执行此操作似乎比在本地计算机上花费的时间更长。由于MongoDB似乎不会等到数据库被完全删除,所以它在旧(删除)数据库中添加了新文档。
为了使我的测试尽可能独立,我通过为每个测试生成不同的唯一数据库名称来解决问题。要清除MongoDB数据库,我们的代码如下所示:
public class MongoDataStoreTest {
private MongoClient client;
@Before
public void before() throws UnknownHostException {
this.client = new MongoClient();
}
@After
public void after() throws InterruptedException {
this.client.dropDatabase("testdb");
this.client.close();
}
}
public void clearData() {
try {
for (String collection : datastore.getDB().getCollectionNames()) {
// We must not mess with system indexes and users as this will cause
// errors
if (!collection.startsWith("system.")) {
// Do not drop the entire database or full collections as this
// will lead to missing index errors (for no obvious reason).
datastore.getDB().getCollection(collection).drop();
}
}
} catch (MongoException e) {
LOG.log(Level.INFO,
"Could not fetch all collection names - this is a permission thing, but can be ignored");
}
// The indexes are not automatically recreated (for no obvious
// reason) - ensure they are still there after the drop().
datastore.ensureIndexes();
datastore.ensureCaps();
}
这可能是一个可能的解决方案,但是我希望我的测试尽可能独立,因此在每次测试之后删除我的完整数据库。我自己解决了这个问题,我将把它添加为一个答案,没有人会删除它并创建一个SQL数据库来进行集成测试。所以,mongo完全有可能避免掉落