Databases 12 min read

Why Your Kingbase JDBC SocketTimeoutException Happens and How to Fix It

This article explains why a Java application using the Kingbase JDBC driver may encounter SocketTimeoutException during reads, analyzes the underlying socket timeout settings in both the driver and Druid connection pool, and provides a step‑by‑step solution to correctly configure timeouts and avoid repeated failures.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Why Your Kingbase JDBC SocketTimeoutException Happens and How to Fix It

Preface

Recently, after committing a transaction, the program reported a submission error even though the data was successfully committed in the database, causing many production issues. This problem is worth every backend developer’s attention because it is rarely encountered.

❝The issue we need to solve is the input‑stream read timeout❞

Socket Basics

Before tackling the problem, review three key socket timeout parameters:

Connect Timeout : Maximum time the client waits to establish a connection. If exceeded, a SocketTimeoutException is thrown. Set via Socket.connect(SocketAddress endpoint, int timeout).

Read Timeout (SO_TIMEOUT) : Maximum time to wait for data on an input stream. If no data arrives, a SocketTimeoutException is thrown. Set via Socket.setSoTimeout(int timeout).

Write Timeout : Maximum time to wait for the remote socket to acknowledge sent data. Usually not needed to set separately.

❝After understanding socket basics, solving the read‑timeout problem becomes straightforward❞

Solution

Problem Investigation

The database is Kingbase 8.6.0 with Druid 1.2.19 connection pool in a master‑slave architecture. By inspecting the source, we found that the socketTimeout property behaves differently in master‑slave mode.

Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    ... (other stack frames omitted)

Key Findings

The default socketTimeout in the driver is 0, meaning no timeout (infinite wait).

In the VisibleBufferedInputStream class, socketTimeout actually controls the number of retry attempts after a read timeout, not the underlying socket read timeout.

Source snippet showing the field:

public class VisibleBufferedInputStream extends InputStream {
    private static final int MINIMUM_READ = 1024;
    private static final int STRING_SCAN_SPAN = 1024;
    private InputStream wrappedInputStream;
    private byte[] _buffer;
    private int _index;
    private int endIndex;
    private String _host;
    private boolean useDispatch;
    private int _version;
    // --------------------------------- this is the configuration we need to confirm ------------
    private int socketTimeout;
}

The default value of socketTimeout is 0, but in master‑slave mode the driver sets a fixed read timeout of 1000 ms (1 s) via Socket.setSoTimeout(1000). The socketTimeout property from the URL is later divided by 1000 and used as the retry count.

socketTimeout configuration
socketTimeout configuration

When useDispatch is true (cluster mode), the read timeout is hard‑coded to 1000 ms; the socketTimeout value from the URL is interpreted as the number of retries (e.g., 3000 ms becomes 3 retries).

retry count illustration
retry count illustration

Practical Fix

Set the Druid property spring.datasource.druid.socket-timeout = 60000 (or any value in milliseconds). This does not change the underlying socket read timeout (still 1 s) but adjusts the retry count accordingly.

❝The configuration actually modifies the retry count, not the socket’s SO_TIMEOUT❞

Verification

After setting socketTimeout to 3000 (3 retries), logs show the retry mechanism triggering as expected:

[2025-07-31 09:00:33] [43] [com.kingbase8.core.VisibleBufferedInputStream-->readMore]   
socketTimeout Exception: useDispatch is true, _host = [node1], master_online_ip = [node1], slave_online_ip = [node2,], currentVersion = [1], lastVersion = [1], socketTimeout = [3]

Conclusion

The socketTimeout field in VisibleBufferedInputStream represents the retry count for read‑timeout exceptions, not the actual socket read timeout.

The real socket read timeout is fixed at 1000 ms in cluster mode and cannot be changed via the URL; it must be configured through the connection pool.

Therefore, configuring socket-timeout in the URL only affects retry attempts, while connect-timeout is multiplied by 1000 (seconds) when the driver creates the socket.

JavaJDBCDruidRead Timeoutdatabase-connectionsocket-timeoutKingbase
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.