Süleyman K
Süleyman K

Reputation: 309

What is the solution "com.mongodb.MongoSocketReadException" and "com.mongodb.MongoTimeoutException"

I use mongo-java-driver 3.1.0. There is no problem connection with JAVA and MongoDB. I can get data from MongoDB and write data into MongoDB by using JAVA.

But when I try to write more data, I get this fault on my java console. I think when socket connection lasts more than 30 seconds, MongoDB client crushes. Until 30 seconds some part of data is inserted to MongoDB (myCollection) First I get;

com.mongodb.MongoSocketReadException: Prematurely reached end of stream

and then

com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}

I did not set any timeout so its timeout should be infinity.

Can someone help

public void writeDB() {

    MongoClient mongoClient = new MongoClient ("127.0.0.1", 27017);
    mongoClient.setWriteConcern(WriteConcern.JOURNALED);

    DB database = mongoClient.getDB("myCollection");    
    BasicDBObject newDataObject = new BasicDBObject();    
    DBCollection collection = database.getCollection("myCollection");    

    int number = 0;    
    for (int i = 0; i <= 1000000; i++) {
    if(CHECKDATA_EXIST) {
        int randomCount = (10 + (Math.random() * 300));    
        for (int j = 0; j < randomCount; j++) {
            number = i + randomCount;
        }

        newDataObject.put("_id", i);
        newDataObject.put("myNumber", number);    
        collection.insert(newDataObject);
    }
    }
}

By the way after crush I cannot write or get any data anymore. To write data, I have to restart "mongod".

I added CHECKDATA_EXIST method for if case (my code includes that). I forgot to add that. That method checks id is exist or not.

Upvotes: 0

Views: 7163

Answers (2)

Daqian
Daqian

Reputation: 84

Hi I have the same problem for a while then I found this http://3t.io/blog/how-to-prevent-your-connection-from-dropping-with-hosted-mongodb-instances/

it says the connection maybe drop after a short period inactive, but will pick it up when you try to connect again.

If your code is long running application I would recommend to change like this: change the connection constructor add MongoClientOptions

    public void writeDB() {

        MongoClientOptions.Builder builder = new MongoClientOptions.Builder();

         //build the connection options  
        builder.maxConnectionIdleTime(60000);//set the max wait time in (ms)
        MongoClientOptions opts = builder.build();


<strike>MongoClient mongoClient = new MongoClient ("127.0.0.1", 27017);</strike>

        MongoClient mongoClient = new MongoClient ("127.0.0.1:27017", opts);
        mongoClient.setWriteConcern(WriteConcern.JOURNALED);

        DB database = mongoClient.getDB("myCollection");    
        BasicDBObject newDataObject = new BasicDBObject();    
        DBCollection collection = database.getCollection("myCollection");



        int number = 0;    
        for (int i = 0; i <= 1000000; i++) {
            if(CHECKDATA_EXIST) {
            int randomCount = (10 + (Math.random() * 300));    
        for (int j = 0; j < randomCount; j++) {
            number = i + randomCount;
        }

        newDataObject.put("_id", i);
        newDataObject.put("myNumber", number);    
        collection.insert(newDataObject);
    }
    }
}

Hope this will help

Upvotes: 1

Neo-coder
Neo-coder

Reputation: 7840

In your code you insert single documents in loops so instead of sending every single document use bulk write changed your code accordingly.

check below code snippet :

DBCollection collection = database.getCollection("myCollection");
BulkWriteOperation  bulkWriteOperation= collection.initializeUnorderedBulkOperation();
 for (int i = 0; i <= 1000000; i++) {
            BasicDBObject newDataObject = new BasicDBObject();
            IncrementalStat incrementalStat = new IncrementalStat();
            double randomCount = (10 + (Math.random() * 300));

            for (int j = 0; j < randomCount; j++) {
                number = i + randomCount;
            }

            newDataObject.put("_id", i);
            newDataObject.put("myNumber", number); 
             bulkWriteOperation.insert(newDataObject);
        }
       //write all data using bulk execute
         BulkWriteResult result=bulkWriteOperation.execute();

Upvotes: 0

Related Questions