简体   繁体   中英

Java async driver for MongoDB doesn't work on replica set when “primary” is changed

I have some troubles with the usage of java async driver ( 3.8.1 ).

I'll describe my environment:

I have a replica set (rs0) with 3 istances: let me call them A,B,C. In my application I use Mongo and two different java driver, sync and async.

At the beginning I reached no problems but when the primary went down (and come up after some minutes changing its behavior as secondary) the part of code when I use async driver was not able to use transactions and session.

The error is the following:

com.mongodb.MongoClientException: Sessions are not supported by the MongoDB cluster to which this client is connected
    at com.mongodb.async.client.MongoClientImpl$1.onResult(MongoClientImpl.java:90)
    at com.mongodb.async.client.MongoClientImpl$1.onResult(MongoClientImpl.java:83)
    at com.mongodb.async.client.ClientSessionHelper$2.onResult(ClientSessionHelper.java:77)
    at com.mongodb.async.client.ClientSessionHelper$2.onResult(ClientSessionHelper.java:73)
    at com.mongodb.internal.connection.BaseCluster$ServerSelectionRequest.onResult(BaseCluster.java:433)
    at com.mongodb.internal.connection.BaseCluster.handleServerSelectionRequest(BaseCluster.java:309)
    at com.mongodb.internal.connection.BaseCluster.access$800(BaseCluster.java:65)
    at com.mongodb.internal.connection.BaseCluster$WaitQueueHandler.run(BaseCluster.java:482)
    at java.lang.Thread.run(Unknown Source)

2019-01-21 17:02:01.906   ERROR 17560 --- [271de4498944329] org.mongodb.driver.client                : Callback onResult call produced an error

java.lang.NullPointerException: null
    at it.mypackage.mongo.service.ProcessoDocumentService$1.onResult(ProcessoDocumentService.java:124)
    at it.mypackage.mongo.service.ProcessoDocumentService$1.onResult(ProcessoDocumentService.java:1)
    at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
    at com.mongodb.async.client.MongoClientImpl$1.onResult(MongoClientImpl.java:90)
    at com.mongodb.async.client.MongoClientImpl$1.onResult(MongoClientImpl.java:83)
    at com.mongodb.async.client.ClientSessionHelper$2.onResult(ClientSessionHelper.java:77)
    at com.mongodb.async.client.ClientSessionHelper$2.onResult(ClientSessionHelper.java:73)
    at com.mongodb.internal.connection.BaseCluster$ServerSelectionRequest.onResult(BaseCluster.java:433)
    at com.mongodb.internal.connection.BaseCluster.handleServerSelectionRequest(BaseCluster.java:309)
    at com.mongodb.internal.connection.BaseCluster.access$800(BaseCluster.java:65)
    at com.mongodb.internal.connection.BaseCluster$WaitQueueHandler.run(BaseCluster.java:482)
    at java.lang.Thread.run(Unknown Source)

Just FYI, if I comment the part of code when I use session and transactions, the error is a classic timeout, as the driver was not longer able to find replica set anymore.

Someone could help me? What I'm missing?

This is how I create my MongoClient:

connectionString = new ConnectionString("mongodb://address1:27017,address2:27018,address3:27019/?replicaSet=rs0");
MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(connectionString)
                    .build();

settings = settings.builder().credential(credential).build();
asyncMongoClientInstance = MongoClients.create(settings);

I found the solution by myself, as the wise man once said: "If you want an help, find it at the end of your arm".

Let's us focus on this part of code:

connectionString = new connectionString("mongodb://address1:27017,address2:27018,address3:27019/?replicaSet=rs0");
MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(connectionString)
                    .build();

settings = settings.builder().credential(credential).build();
asyncMongoClientInstance = MongoClients.create(settings);

I'm reallocating the settings object to another object without the connection string. So, async library doesn't know anymore where to address the connection.

Why I did that? I wanted to dinamically add credentials to the settings. But is not possible in this way. So I created two different settings object, one with credentials and one without.

MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(connectionString).credential(credential).build();

It definitely works with this object now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM