diff --git a/README.md b/README.md
index 07943436..66ef2a25 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ To get the Java connector for Tarantool 1.6.9, visit
 
 ## Getting started
 
-1. Add a dependency to your `pom.xml` file.
+1. Add a dependency to your `pom.xml` file:
 
 ```xml
 
@@ -32,7 +32,7 @@ To get the Java connector for Tarantool 1.6.9, visit
 
 ```
 
-2. Configure `TarantoolClientConfig`.
+2. Configure `TarantoolClientConfig`:
 
 ```java
 TarantoolClientConfig config = new TarantoolClientConfig();
@@ -40,67 +40,73 @@ config.username = "test";
 config.password = "test";
 ```
 
-3. Implement your `SocketChannelProvider`.
-   It should return a connected `SocketChannel`.
+3. Create a client:
 
 ```java
-SocketChannelProvider socketChannelProvider = new SocketChannelProvider() {
-           @Override
-           public SocketChannel get(int retryNumber, Throwable lastError) {
-               if (lastError != null) {
-                   lastError.printStackTrace(System.out);
-               }
-               try {
-                   return SocketChannel.open(new InetSocketAddress("localhost", 3301));
-               } catch (IOException e) {
-                   throw new IllegalStateException(e);
-               }
-           }
-       };
+TarantoolClient client = new TarantoolClientImpl("host:3301", config);
 ```
 
-Here you could also implement some reconnection or fallback policy.
-Remember that `TarantoolClient` adopts a
-[fail-fast](https://en.wikipedia.org/wiki/Fail-fast) policy
-when a client is not connected.
+using `TarantoolClientImpl(String, TarantoolClientConfig)` is equivalent to:
 
-The `TarantoolClient` will stop functioning if your implementation of a socket
-channel provider raises an exception or returns a null. You will need a new
-instance of client to recover. Hence, you should only throw in case you have
-met unrecoverable error.
+```java
+SocketChannelProvider socketChannelProvider = new SingleSocketChannelProviderImpl("host:3301")
+TarantoolClient client = new TarantoolClientImpl(socketChannelProvider, config);
+```
 
-Below is an example of `SocketChannelProvider` implementation that handles short
-tarantool restarts.
+You could implement your own `SocketChannelProvider`. It should return 
+a connected `SocketChannel`. Feel free to implement `get(int retryNumber, Throwable lastError)`
+using your appropriate strategy to obtain the channel. The strategy can take into
+account current attempt number (retryNumber) and the last transient error occurred on
+the previous attempt.
+
+The `TarantoolClient` will be closed if your implementation of a socket
+channel provider raises exceptions. However, throwing a `SocketProviderTransientException`
+or returning `null` value are handled by the client as recoverable errors. In these cases,
+the client will make next attempt to obtain the socket channel. Otherwise, you will need
+a new instance of client to recover. Hence, you should only throw an error different
+to `SocketProviderTransientException` in case you have met unrecoverable error.
+
+Below is an example of `SocketChannelProvider` implementation that tries
+to connect no more than 3 times, two seconds for each attempt at max.
 
 ```java
 SocketChannelProvider socketChannelProvider = new SocketChannelProvider() {
     @Override
     public SocketChannel get(int retryNumber, Throwable lastError) {
-        long deadline = System.currentTimeMillis() + RESTART_TIMEOUT;
-        while (!Thread.currentThread().isInterrupted()) {
-            try {
-                return SocketChannel.open(new InetSocketAddress("localhost", 3301));
-            } catch (IOException e) {
-                if (deadline < System.currentTimeMillis())
-                    throw new RuntimeException(e);
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException ignored) {
-                    Thread.currentThread().interrupt();
-                }
+        if (retryNumber > 3) {
+            throw new RuntimeException("Too many attempts");
+        }
+        SocketChannel channel = null;
+        try {
+            channel = SocketChannel.open();
+            channel.socket().connect(new InetSocketAddress("localhost", 3301), 2000);
+            return channel;
+        } catch (IOException e) {
+            if (channel != null) {
+                 try {
+                     channel.close();
+                 } catch (IOException ignored) { }
             }
+            throw new SocketProviderTransientException("Couldn't connect to server", e);
         }
-        throw new RuntimeException(new TimeoutException("Connect timed out."));
     }
 };
 ```
 
-4. Create a client.
+Same behaviour can be achieved using built-in `SingleSocketChannelProviderImpl`:
 
 ```java
+TarantoolClientConfig config = new TarantoolClientConfig();
+config.connectionTimeout = 2_000; // two seconds timeout per attempt
+config.retryCount = 3;            // three attempts at max
+
+SocketChannelProvider socketChannelProvider = new SingleSocketChannelProviderImpl("localhost:3301")
 TarantoolClient client = new TarantoolClientImpl(socketChannelProvider, config);
 ```
 
+`SingleSocketChannelProviderImpl` implements `ConfigurableSocketChannelProvider` that
+makes possible for the client to configure a socket provider.
+
 > **Notes:**
 > * `TarantoolClient` is thread-safe and asynchronous, so you should use one
 >   client inside the whole application.
@@ -168,6 +174,21 @@ a list of nodes which will be used by the cluster client to provide such
 ability. Also you can prefer to use a [discovery mechanism](#auto-discovery)
 in order to dynamically fetch and apply the node list.
 
+### The RoundRobinSocketProviderImpl class
+
+This cluster-aware provider uses addresses pool to connect to DB server.
+The provider picks up next address in order the addresses were passed.
+
+Similar to `SingleSocketChannelProviderImpl` this RR provider also
+relies on two options from the config: `TarantoolClientConfig.connectionTimeout`
+and `TarantoolClientConfig.retryCount` but in a bit different way.
+The latter option says how many times the provider should try to establish a
+connection to _one instance_ before failing an attempt. The provider requires
+positive retry count to work properly. The socket timeout is used to limit
+an interval between connections attempts per instance. In other words, the provider
+follows a pattern _connection should succeed after N attempts with M interval between
+them at max_. 
+
 ### Basic cluster client usage
 
 1. Configure `TarantoolClusterClientConfig`:
@@ -198,7 +219,7 @@ client.syncOps().insert(23, Arrays.asList(1, 1));
 Auto-discovery feature allows a cluster client to fetch addresses of 
 cluster nodes to reflect changes related to the cluster topology. To achieve
 this you have to create a Lua function on the server side which returns 
-a single array result. Client periodically pools the server to obtain a 
+a single array result. Client periodically polls the server to obtain a 
 fresh list and apply it if its content changes.
 
 1. On the server side create a function which returns nodes:
diff --git a/src/main/java/org/tarantool/BaseSocketChannelProvider.java b/src/main/java/org/tarantool/BaseSocketChannelProvider.java
index a532bcdf..2b85a934 100644
--- a/src/main/java/org/tarantool/BaseSocketChannelProvider.java
+++ b/src/main/java/org/tarantool/BaseSocketChannelProvider.java
@@ -4,7 +4,7 @@
 import java.net.InetSocketAddress;
 import java.nio.channels.SocketChannel;
 
-public abstract class BaseSocketChannelProvider implements SocketChannelProvider {
+public abstract class BaseSocketChannelProvider implements ConfigurableSocketChannelProvider {
 
     /**
      * Limit of retries.
@@ -14,61 +14,39 @@ public abstract class BaseSocketChannelProvider implements SocketChannelProvider
     /**
      * Timeout to establish socket connection with an individual server.
      */
-    private int timeout = NO_TIMEOUT;
+    private int connectionTimeout = NO_TIMEOUT;
 
     /**
      * Tries to establish a new connection to the Tarantool instances.
      *
-     * @param retryNumber number of current retry. Reset after successful connect.
+     * @param retryNumber number of current retry
      * @param lastError   the last error occurs when reconnecting
      *
      * @return connected socket channel
      *
-     * @throws CommunicationException if any I/O errors happen or there are
-     *                                no addresses available
+     * @throws CommunicationException           if number of retries or socket timeout are exceeded
+     * @throws SocketProviderTransientException if any I/O errors happen
      */
     @Override
     public final SocketChannel get(int retryNumber, Throwable lastError) {
-        if (areRetriesExhausted(retryNumber)) {
-            throw new CommunicationException("Connection retries exceeded.", lastError);
-        }
-
-        long deadline = System.currentTimeMillis() + timeout;
-        while (!Thread.currentThread().isInterrupted()) {
-            try {
-                InetSocketAddress address = getAddress(retryNumber, lastError);
-                return openChannel(address);
-            } catch (IOException e) {
-                checkTimeout(deadline, e);
-            }
-        }
-        throw new CommunicationException("Thread interrupted.", new InterruptedException());
-    }
-
-    private void checkTimeout(long deadline, Exception e) {
-        long timeLeft = deadline - System.currentTimeMillis();
-        if (timeLeft <= 0) {
-            throw new CommunicationException("Connection time out.", e);
-        }
         try {
-            Thread.sleep(timeLeft / 10);
-        } catch (InterruptedException ignored) {
-            Thread.currentThread().interrupt();
+            return makeAttempt(retryNumber, lastError);
+        } catch (IOException e) {
+            throw new SocketProviderTransientException("Couldn't connect to the server", e);
         }
     }
 
     /**
-     * Gets address to be used to establish a new connection
-     * Address can be null.
+     * Obtains a connected socket channel.
      *
      * @param retryNumber reconnection attempt number
      * @param lastError   reconnection reason
      *
-     * @return available address which is depended on implementation
+     * @return opened socket channel
      *
      * @throws IOException if any I/O errors occur
      */
-    protected abstract InetSocketAddress getAddress(int retryNumber, Throwable lastError) throws IOException;
+    protected abstract SocketChannel makeAttempt(int retryNumber, Throwable lastError) throws IOException;
 
     /**
      * Sets maximum amount of reconnect attempts to be made before an exception is raised.
@@ -79,7 +57,11 @@ private void checkTimeout(long deadline, Exception e) {
      *
      * @param retriesLimit Limit of retries to use.
      */
+    @Override
     public void setRetriesLimit(int retriesLimit) {
+        if (retriesLimit < 0) {
+            throw new IllegalArgumentException("Retries count cannot be negative.");
+        }
         this.retriesLimit = retriesLimit;
     }
 
@@ -111,7 +93,7 @@ protected SocketChannel openChannel(InetSocketAddress socketAddress) throws IOEx
         SocketChannel channel = null;
         try {
             channel = SocketChannel.open();
-            channel.socket().connect(socketAddress, timeout);
+            channel.socket().connect(socketAddress, connectionTimeout);
             return channel;
         } catch (IOException e) {
             if (channel != null) {
@@ -126,44 +108,31 @@ protected SocketChannel openChannel(InetSocketAddress socketAddress) throws IOEx
     }
 
     /**
-     * Sets maximum amount of time to wait for a socket connection establishment
-     * with an individual server.
-     * 
-     * Zero means infinite timeout.
-     *
-     * @param timeout timeout value, ms.
-     *
-     * @throws IllegalArgumentException if timeout is negative.
-     */
-    public void setTimeout(int timeout) {
-        if (timeout < 0) {
-            throw new IllegalArgumentException("timeout is negative.");
-        }
-        this.timeout = timeout;
-    }
-
-    /**
-     * Gest maximum amount of time to wait for a socket
+     * Gets maximum amount of time to wait for a socket
      * connection establishment with an individual server.
      *
      * @return timeout
      */
-    public int getTimeout() {
-        return timeout;
+    public int getConnectionTimeout() {
+        return connectionTimeout;
     }
 
     /**
-     * Provides a decision on whether retries limit is hit.
+     * Sets maximum amount of time to wait for a socket connection establishment
+     * with an individual server.
+     * 
+     * Zero means infinite connectionTimeout.
      *
-     * @param retries Current count of retries.
+     * @param connectionTimeout connectionTimeout value, ms.
      *
-     * @return {@code true} if retries are exhausted.
+     * @throws IllegalArgumentException if connectionTimeout is negative.
      */
-    private boolean areRetriesExhausted(int retries) {
-        int limit = getRetriesLimit();
-        if (limit < 0) {
-            return false;
+    @Override
+    public void setConnectionTimeout(int connectionTimeout) {
+        if (connectionTimeout < 0) {
+            throw new IllegalArgumentException("Connection timeout cannot be negative.");
         }
-        return retries >= limit;
+        this.connectionTimeout = connectionTimeout;
     }
+
 }
diff --git a/src/main/java/org/tarantool/ConfigurableSocketChannelProvider.java b/src/main/java/org/tarantool/ConfigurableSocketChannelProvider.java
new file mode 100644
index 00000000..2c04ea64
--- /dev/null
+++ b/src/main/java/org/tarantool/ConfigurableSocketChannelProvider.java
@@ -0,0 +1,23 @@
+package org.tarantool;
+
+public interface ConfigurableSocketChannelProvider extends SocketChannelProvider {
+
+    int RETRY_NO_LIMIT = 0;
+    int NO_TIMEOUT = 0;
+
+    /**
+     * Configures max count of retries.
+     *
+     * @param limit max attempts count
+     */
+    void setRetriesLimit(int limit);
+
+    /**
+     * Configures max time to establish
+     * a connection per attempt.
+     *
+     * @param timeout connection timeout in millis
+     */
+    void setConnectionTimeout(int timeout);
+
+}
diff --git a/src/main/java/org/tarantool/RoundRobinSocketProviderImpl.java b/src/main/java/org/tarantool/RoundRobinSocketProviderImpl.java
index 24820a03..1107799c 100644
--- a/src/main/java/org/tarantool/RoundRobinSocketProviderImpl.java
+++ b/src/main/java/org/tarantool/RoundRobinSocketProviderImpl.java
@@ -3,6 +3,7 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
+import java.nio.channels.SocketChannel;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -21,6 +22,7 @@
 public class RoundRobinSocketProviderImpl extends BaseSocketChannelProvider implements RefreshableSocketProvider {
 
     private static final int UNSET_POSITION = -1;
+    private static final int DEFAULT_RETRIES_PER_CONNECTION = 3;
 
     /**
      * Socket addresses pool.
@@ -59,6 +61,7 @@ public class RoundRobinSocketProviderImpl extends BaseSocketChannelProvider impl
      */
     public RoundRobinSocketProviderImpl(String... addresses) {
         updateAddressList(Arrays.asList(addresses));
+        setRetriesLimit(DEFAULT_RETRIES_PER_CONNECTION);
     }
 
     private void updateAddressList(Collection addresses) {
@@ -116,9 +119,55 @@ protected InetSocketAddress getLastObtainedAddress() {
         }
     }
 
+    /**
+     * Tries to open a socket channel to a next instance
+     * for the addresses list.
+     *
+     * There are {@link #getRetriesLimit()} attempts per
+     * call to initiate a connection to the instance.
+     *
+     * @param retryNumber reconnection attempt number
+     * @param lastError   reconnection reason
+     *
+     * @return opened socket channel
+     *
+     * @throws IOException            if any IO errors occur
+     * @throws CommunicationException if retry number exceeds addresses size
+     *
+     * @see #setRetriesLimit(int)
+     * @see #getAddresses()
+     */
+    @Override
+    protected SocketChannel makeAttempt(int retryNumber, Throwable lastError) throws IOException {
+        if (retryNumber > getAddressCount()) {
+            throwFatalError("No more connection addresses are left.");
+        }
+
+        int retriesLimit = getRetriesLimit();
+        InetSocketAddress socketAddress = getNextSocketAddress();
+        IOException connectionError = null;
+        for (int i = 0; i < retriesLimit; i++) {
+            try {
+                return openChannel(socketAddress);
+            } catch (IOException e) {
+                connectionError = e;
+            }
+        }
+        throw connectionError;
+    }
+
+    /**
+     * Sets a retries count per instance.
+     * 0 (infinite) count is not supported by this provider.
+     *
+     * @param retriesLimit limit of retries to use.
+     */
     @Override
-    protected InetSocketAddress getAddress(int retryNumber, Throwable lastError) throws IOException {
-        return getNextSocketAddress();
+    public void setRetriesLimit(int retriesLimit) {
+        if (retriesLimit == 0) {
+            throwFatalError("Retries count should be at least 1 or more");
+        }
+        super.setRetriesLimit(retriesLimit);
     }
 
     /**
@@ -163,4 +212,8 @@ public void refreshAddresses(Collection addresses) {
         updateAddressList(addresses);
     }
 
+    private void throwFatalError(String message) {
+        throw new CommunicationException(message);
+    }
+
 }
diff --git a/src/main/java/org/tarantool/SingleSocketChannelProviderImpl.java b/src/main/java/org/tarantool/SingleSocketChannelProviderImpl.java
index 0829bdc2..ef1fc59b 100644
--- a/src/main/java/org/tarantool/SingleSocketChannelProviderImpl.java
+++ b/src/main/java/org/tarantool/SingleSocketChannelProviderImpl.java
@@ -5,6 +5,7 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
+import java.nio.channels.SocketChannel;
 
 /**
  * Simple provider that produces a single connection.
@@ -28,8 +29,26 @@ public SocketAddress getAddress() {
     }
 
     @Override
-    protected InetSocketAddress getAddress(int retryNumber, Throwable lastError) throws IOException {
-        return address;
+    protected SocketChannel makeAttempt(int retryNumber, Throwable lastError) throws IOException {
+        if (areRetriesExhausted(retryNumber)) {
+            throw new CommunicationException("Connection retries exceeded.", lastError);
+        }
+        return openChannel(address);
+    }
+
+    /**
+     * Provides a decision on whether retries limit is hit.
+     *
+     * @param retryNumber current count of retries.
+     *
+     * @return {@code true} if retries are exhausted.
+     */
+    private boolean areRetriesExhausted(int retryNumber) {
+        int limit = getRetriesLimit();
+        if (limit < 1) {
+            return false;
+        }
+        return retryNumber >= limit;
     }
 
     public void setAddress(String address) {
diff --git a/src/main/java/org/tarantool/SocketChannelProvider.java b/src/main/java/org/tarantool/SocketChannelProvider.java
index e4f26d79..a811bb1f 100644
--- a/src/main/java/org/tarantool/SocketChannelProvider.java
+++ b/src/main/java/org/tarantool/SocketChannelProvider.java
@@ -1,18 +1,22 @@
 package org.tarantool;
 
+import java.net.SocketAddress;
 import java.nio.channels.SocketChannel;
 
 public interface SocketChannelProvider {
 
-    int RETRY_NO_LIMIT = -1;
-    int NO_TIMEOUT = 0;
-
     /**
      * Provides socket channel to init restore connection.
-     * You could change hosts on fail and sleep between retries in this method
-     * @param retryNumber number of current retry. Reset after successful connect.
+     * You could change hosts between retries in this method.
+     *
+     * @param retryNumber number of current retry.
      * @param lastError   the last error occurs when reconnecting
-     * @return the result of SocketChannel open(SocketAddress remote) call
+     *
+     * @return the result of {@link SocketChannel#open(SocketAddress)} call
+     *
+     * @throws SocketProviderTransientException if recoverable error occurred
+     * @throws RuntimeException                 if any other reasons occurred
      */
     SocketChannel get(int retryNumber, Throwable lastError);
+
 }
diff --git a/src/main/java/org/tarantool/SocketProviderTransientException.java b/src/main/java/org/tarantool/SocketProviderTransientException.java
new file mode 100644
index 00000000..5a378903
--- /dev/null
+++ b/src/main/java/org/tarantool/SocketProviderTransientException.java
@@ -0,0 +1,9 @@
+package org.tarantool;
+
+public class SocketProviderTransientException extends RuntimeException {
+
+    public SocketProviderTransientException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/src/main/java/org/tarantool/TarantoolClientConfig.java b/src/main/java/org/tarantool/TarantoolClientConfig.java
index 43f06746..6ddc40fb 100644
--- a/src/main/java/org/tarantool/TarantoolClientConfig.java
+++ b/src/main/java/org/tarantool/TarantoolClientConfig.java
@@ -36,6 +36,11 @@ public class TarantoolClientConfig {
      */
     public double directWriteFactor = 0.5d;
 
+    /**
+     * Write operation timeout.
+     */
+    public long writeTimeoutMillis = 60 * 1000L;
+
     /**
      * Use old call command https://github.com/tarantool/doc/issues/54,
      * please ensure that you server supports new call command.
@@ -43,9 +48,23 @@ public class TarantoolClientConfig {
     public boolean useNewCall = false;
 
     /**
-     * Limits for synchronous operations.
+     *  Max time to establish connection to the server
+     *  and be completely configured (to have an {@code ALIVE} status).
+     *
+     * @see TarantoolClient#isAlive()
      */
     public long initTimeoutMillis = 60 * 1000L;
-    public long writeTimeoutMillis = 60 * 1000L;
+
+    /**
+     * Connection timeout per attempt.
+     * {@code 0} means no timeout.
+     */
+    public int connectionTimeout = 2 * 1000;
+
+    /**
+     * Total attempts number to connect to DB.
+     * {@code 0} means unlimited attempts.
+     */
+    public int retryCount = 3;
 
 }
diff --git a/src/main/java/org/tarantool/TarantoolClientImpl.java b/src/main/java/org/tarantool/TarantoolClientImpl.java
index 12d8f676..7c53cfeb 100644
--- a/src/main/java/org/tarantool/TarantoolClientImpl.java
+++ b/src/main/java/org/tarantool/TarantoolClientImpl.java
@@ -73,7 +73,7 @@ public class TarantoolClientImpl extends TarantoolBase> implements Tar
         @Override
         public void run() {
             while (!Thread.currentThread().isInterrupted()) {
-                reconnect(0, thumbstone);
+                reconnect(thumbstone);
                 try {
                     state.awaitReconnection();
                 } catch (InterruptedException e) {
@@ -88,7 +88,16 @@ public TarantoolClientImpl(String address, TarantoolClientConfig config) {
     }
 
     public TarantoolClientImpl(SocketChannelProvider socketProvider, TarantoolClientConfig config) {
-        super();
+        initClient(socketProvider, config);
+        if (socketProvider instanceof ConfigurableSocketChannelProvider) {
+            ConfigurableSocketChannelProvider configurableProvider = (ConfigurableSocketChannelProvider) socketProvider;
+            configurableProvider.setConnectionTimeout(config.connectionTimeout);
+            configurableProvider.setRetriesLimit(config.retryCount);
+        }
+        startConnector(config.initTimeoutMillis);
+    }
+
+    private void initClient(SocketChannelProvider socketProvider, TarantoolClientConfig config) {
         this.thumbstone = NOT_INIT_EXCEPTION;
         this.config = config;
         this.initialRequestSize = config.defaultRequestSize;
@@ -108,16 +117,14 @@ public TarantoolClientImpl(SocketChannelProvider socketProvider, TarantoolClient
             this.fireAndForgetOps.setCallCode(Code.CALL);
             this.composableAsyncOps.setCallCode(Code.CALL);
         }
-
-        startConnector(config);
     }
 
-    private void startConnector(TarantoolClientConfig config) {
+    private void startConnector(long initTimeoutMillis) {
         connector.start();
         try {
-            if (!waitAlive(config.initTimeoutMillis, TimeUnit.MILLISECONDS)) {
+            if (!waitAlive(initTimeoutMillis, TimeUnit.MILLISECONDS)) {
                 CommunicationException e = new CommunicationException(
-                    config.initTimeoutMillis +
+                    initTimeoutMillis +
                         "ms is exceeded when waiting for client initialization. " +
                         "You could configure init timeout in TarantoolConfig"
                 );
@@ -131,18 +138,25 @@ private void startConnector(TarantoolClientConfig config) {
         }
     }
 
-    protected void reconnect(int retry, Throwable lastError) {
-        SocketChannel channel;
+    protected void reconnect(Throwable lastError) {
+        SocketChannel channel = null;
+        int retryNumber = 0;
         while (!Thread.currentThread().isInterrupted()) {
             try {
-                channel = socketProvider.get(retry++, lastError == NOT_INIT_EXCEPTION ? null : lastError);
+                channel = socketProvider.get(retryNumber++, lastError == NOT_INIT_EXCEPTION ? null : lastError);
             } catch (Exception e) {
-                close(e);
-                return;
+                closeChannel(channel);
+                lastError = e;
+                if (!(e instanceof SocketProviderTransientException)) {
+                    close(e);
+                    return;
+                }
             }
             try {
-                connect(channel);
-                return;
+                if (channel != null) {
+                    connect(channel);
+                    return;
+                }
             } catch (Exception e) {
                 closeChannel(channel);
                 lastError = e;
@@ -838,6 +852,7 @@ public TarantoolOp(Code code) {
         public Code getCode() {
             return code;
         }
+
     }
 
 }
diff --git a/src/main/java/org/tarantool/TarantoolClusterClient.java b/src/main/java/org/tarantool/TarantoolClusterClient.java
index 49fdb4af..7b71f10e 100644
--- a/src/main/java/org/tarantool/TarantoolClusterClient.java
+++ b/src/main/java/org/tarantool/TarantoolClusterClient.java
@@ -52,7 +52,7 @@ public class TarantoolClusterClient extends TarantoolClientImpl {
      * @param addresses Array of addresses in the form of host[:port].
      */
     public TarantoolClusterClient(TarantoolClusterClientConfig config, String... addresses) {
-        this(config, makeClusterSocketProvider(addresses, config.operationExpiryTimeMillis));
+        this(config, makeClusterSocketProvider(addresses));
     }
 
     /**
@@ -268,11 +268,8 @@ public void refreshInstances() {
         }
     }
 
-    private static RoundRobinSocketProviderImpl makeClusterSocketProvider(String[] addresses,
-                                                                          int connectionTimeout) {
-        RoundRobinSocketProviderImpl socketProvider = new RoundRobinSocketProviderImpl(addresses);
-        socketProvider.setTimeout(connectionTimeout);
-        return socketProvider;
+    private static RoundRobinSocketProviderImpl makeClusterSocketProvider(String[] addresses) {
+        return new RoundRobinSocketProviderImpl(addresses);
     }
 
     private Runnable createDiscoveryTask(TarantoolClusterDiscoverer serviceDiscoverer) {
diff --git a/src/test/java/org/tarantool/RoundRobinSocketProviderImplTest.java b/src/test/java/org/tarantool/RoundRobinSocketProviderImplTest.java
index f494be47..ee1f2563 100644
--- a/src/test/java/org/tarantool/RoundRobinSocketProviderImplTest.java
+++ b/src/test/java/org/tarantool/RoundRobinSocketProviderImplTest.java
@@ -68,7 +68,7 @@ public void testResultWithWrongAddress() throws IOException {
     public void testDefaultTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
-        assertEquals(RoundRobinSocketProviderImpl.NO_TIMEOUT, socketProvider.getTimeout());
+        assertEquals(RoundRobinSocketProviderImpl.NO_TIMEOUT, socketProvider.getConnectionTimeout());
     }
 
     @Test
@@ -77,8 +77,8 @@ public void testChangingTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
         int expectedTimeout = 10_000;
-        socketProvider.setTimeout(expectedTimeout);
-        assertEquals(expectedTimeout, socketProvider.getTimeout());
+        socketProvider.setConnectionTimeout(expectedTimeout);
+        assertEquals(expectedTimeout, socketProvider.getConnectionTimeout());
     }
 
     @Test
@@ -87,7 +87,7 @@ public void testWrongChangingTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
         int negativeValue = -200;
-        assertThrows(IllegalArgumentException.class, () -> socketProvider.setTimeout(negativeValue));
+        assertThrows(IllegalArgumentException.class, () -> socketProvider.setConnectionTimeout(negativeValue));
     }
 
     @Test
@@ -125,11 +125,11 @@ public void testTooManyAttempts() throws IOException {
         RoundRobinSocketProviderImpl socketProvider
                 = wrapWithMockChannelProvider(new RoundRobinSocketProviderImpl(addresses));
 
-        int retriesLimit = 5;
+        int retriesLimit = addresses.length + 1;
         socketProvider.setRetriesLimit(retriesLimit);
 
         for (int i = 0; i < retriesLimit; i++) {
-            socketProvider.get(0, null);
+            socketProvider.get(i, null);
             assertEquals(expectedAddress, extractRawHostAndPortString(socketProvider.getLastObtainedAddress()));
         }
 
@@ -141,7 +141,7 @@ public void testTooManyAttempts() throws IOException {
     public void testWrongAddress() throws IOException {
         RoundRobinSocketProviderImpl socketProvider
                 = wrapWithMockErroredChannelProvider(new RoundRobinSocketProviderImpl("unreachable-host:3301"));
-        assertThrows(CommunicationException.class, () -> socketProvider.get(0, null));
+        assertThrows(SocketProviderTransientException.class, () -> socketProvider.get(0, null));
     }
 
     @Test
@@ -149,7 +149,7 @@ public void testWrongAddress() throws IOException {
     public void testWrongRefreshAddress() throws IOException {
         RoundRobinSocketProviderImpl socketProvider
                 = wrapWithMockErroredChannelProvider(new RoundRobinSocketProviderImpl("unreachable-host:3301"));
-        assertThrows(CommunicationException.class, () -> socketProvider.get(0, null));
+        assertThrows(SocketProviderTransientException.class, () -> socketProvider.get(0, null));
     }
 
 }
diff --git a/src/test/java/org/tarantool/SingleSocketChannelProviderImplTest.java b/src/test/java/org/tarantool/SingleSocketChannelProviderImplTest.java
index a7a53fb4..9c7f54ff 100644
--- a/src/test/java/org/tarantool/SingleSocketChannelProviderImplTest.java
+++ b/src/test/java/org/tarantool/SingleSocketChannelProviderImplTest.java
@@ -31,7 +31,7 @@ public void testEmptyAddresses() {
     public void testDefaultTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
-        assertEquals(RoundRobinSocketProviderImpl.NO_TIMEOUT, socketProvider.getTimeout());
+        assertEquals(RoundRobinSocketProviderImpl.NO_TIMEOUT, socketProvider.getConnectionTimeout());
     }
 
     @Test
@@ -40,8 +40,8 @@ public void testChangingTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
         int expectedTimeout = 10_000;
-        socketProvider.setTimeout(expectedTimeout);
-        assertEquals(expectedTimeout, socketProvider.getTimeout());
+        socketProvider.setConnectionTimeout(expectedTimeout);
+        assertEquals(expectedTimeout, socketProvider.getConnectionTimeout());
     }
 
     @Test
@@ -50,7 +50,7 @@ public void testWrongChangingTimeout() {
         RoundRobinSocketProviderImpl socketProvider
                 = new RoundRobinSocketProviderImpl("localhost");
         int negativeValue = -100;
-        assertThrows(IllegalArgumentException.class, () -> socketProvider.setTimeout(negativeValue));
+        assertThrows(IllegalArgumentException.class, () -> socketProvider.setConnectionTimeout(negativeValue));
     }
 
     @Test