0

I am inserting lot of records into DB in a multithreaded java program.

The main thred creates all the threads and waits for them to complete.

for(int i = 0; i < noOfThreads; i++) {
results.add(exec.submit(new InsertConnection()) );
Thread.sleep(1000);
}

for(Future<?> fs : results) {
try {
// This will wait till each thread is done
fs.get();
} catch (Exception e) { 
logger.error(null, e);
} 
}

Each of the threads operate on a DB connection and they insert records into the DB. The connection object is not shared between threads. something like this

public class InsertConnection implements Runnable{

    public InsertConnection() {
        //create connection object
    }

@Override
public void run() {
    while(true)
       //Fetch a betch
       //Insert ina loop
        }
    }
}

Just before the program is over I see some threads (2, 4 6) fail to insert because connection is closed. I think when 1 thread finishes it's job the socket is closed somehow. Below is the exception

** BEGIN NESTED EXCEPTION ** 

com.mysql.jdbc.CommunicationsException
MESSAGE: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.SocketException
MESSAGE: Software caused connection abort: recv failed

STACKTRACE:

java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:113)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:160)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:188)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1994)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:3283)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1332)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:882)
    at com.mysql.jdbc.CallableStatement.execute(CallableStatement.java:759)
    at mind.fire.connection.store.InsertConnection.execute(InsertConnection.java:81)
    at mind.fire.connection.store.InsertConnection.run(InsertConnection.java:62)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)


** END NESTED EXCEPTION **
bomaboom
  • 190
  • 1
  • 14
  • 1
    Are you using a JDBC connection pool? http://stackoverflow.com/questions/2835090/jdbc-connection-pooling – NickJ Apr 17 '13 at 10:17
  • Need to see the code you are using to make a connection. Also, you really should use a completion service on your main thread (you have the perfect use case for it). – Perception Apr 17 '13 at 10:52
  • I have created my own connection pool. It just has 2 vectors availableconnection and busyconnection and the connections switch between these 2. I have a singleton class which ensures that only 1 connectionpool instance of connection pool object can be created, – bomaboom Apr 17 '13 at 11:14
  • Connection pool https://www.dropbox.com/s/vimngsyo0d8odcm/ConnectionPool.java Singleton instance of connection pool https://www.dropbox.com/s/2rfoicz10k5829k/MySqlHelper.java creating connection and executing https://www.dropbox.com/s/e3v21s48wbk99hc/InsertConnection.java – bomaboom Apr 17 '13 at 11:23

0 Answers0