在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

我正在测试Java应用程序中将数据存储在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();
  }
在我的测试中,我执行了以下代码:

  • 我创建了一个DB实例,其中包含:
    DB database=client.getDB(“testdb”)
  • 我在数据库中添加了一个集合:
    database.getCollection(“testcoll”)
  • 然后我插入一个基本的CDBObject:
    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完全有可能避免掉落