I've been writing a Java application that parses flat files and inserts them into MS SQL Server 2000 using JDBC. The code itself works, just that as it runs, it gets slower and slower - to ultra-turtle speed - and occassionally even crashes with the following error:
"Connection reset by peer: socket write error"
Among the data it parses are Strings, which often are concatenations weighing in at 300,000 characters long, and commonly longer.
Our highly-qualified and always-willing-to-help DBA informed me that the number of connections I've been maintaining with the database has varied between 2 and over 100(!). I am not doing any parallel processing, therefore, the maximum number of connections I'd ever expect at any given time should be 1. Another strange thing she told me is that when she runs a trace of the activity my computer is generating to the database, it shows many, many logons and logoffs, and not necessarily one at a time. For example, it might look like this: logon, logon, logon, logon, logoff, logoff, logon, etc...
It seems that for each SQL call a new connection is being created. Or perhaps the connections are never getting closed properly.
I've attached code from two of my classes below: DBConnection and InsertSequence. There is another class (not attached) that instantiates DBConnection (once per file parsed) and InsertSequence (once per record). Shouldn't the finalize method in InsertSequence (code below) be implicitly called to close all open connections?
We have been banging our head against the proverbial wall for quite a while here and it is really starting to hurt. Any help would be completely and totally appreciated!
RebLazer
Chicago, IL
********************
import java.sql.*;
public class DBConnection
{
public Connection con;
public DBConnection()
{
//constructor loads SQL DB Driver and sets up connection and statement objects
try
{
Class.forName(SSSConstants.driverClass);
}
catch(ClassNotFoundException e)
{
System.out.println("Unable to load Driver Class"
return;
}
try
{
//Create Connection
con = DriverManager.getConnection("jdbc:microsoft:sqlserver://10.3.55.117;selectMethod=cursor;programName=SSS_Parser", "reblazer", "reblazer1"
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
}
public void finalize()
{
try
{
//release resources upon exiting
con.close();
this.finalize();
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
}
/**
* Method to insert files that has been parsed from the database
* @param sqlString A variable of Type String. This is the Insert statement.
* @return res Returns variable of type boolean to indicate that rows have been inserted.
*/
public ResultSet insert(String sqlString)
{
ResultSet rs = null;
Statement sql = null;
try
{
//execute statement and return results
rs = sql.executeQuery(sqlString);
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
return rs;
}
/**
* Method to run query against DB for sequences that match user input
* @param sqlString A variable of Type String. This is the Select statement.
* @return rs This is the Resultset which is passed back to the calling program
*/
public ResultSet query(String sqlString)
{
ResultSet rs = null;//ResultSet is not needed but it must be set to null
try
{
//Create Statement
Statement sql = con.createStatement();
//execute statement and return results
rs = sql.executeQuery(sqlString);
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
return rs;
}
}
public class InsertSequence extends DBConnection
{
NucSeq nucSeqSingle;
public InsertSequence()
{
super();
}
public InsertionCodes checkAccession(NucSeq nucSeqSingle, DBConnection dbConn) {
try {
CallableStatement cs = con.prepareCall("{call Genomics.CHECK_SEQ_DATA (?,?,?,?,?,?,?,?)}"
cs.setString(1, nucSeqSingle.getComName());
cs.setString(2, nucSeqSingle.getOriginalDB());
cs.setString(3, nucSeqSingle.getCategory());
cs.setString(4, nucSeqSingle.getSubInd());
cs.setString(5, nucSeqSingle.getAccession());
cs.setString(6, nucSeqSingle.getAccVer());
cs.setInt (7, nucSeqSingle.getGi());
cs.setString(8, nucSeqSingle.getDescription());
ResultSet rs = cs.executeQuery();
rs.next();
InsertionCodes insCodes = new InsertionCodes(rs.getInt(2));
return insCodes;
}
catch (SQLException se) {
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
return null;
}
}
public InsertionCodes doInsert(NucSeq nucSeqSingle, DBConnection dbConn) {
try {
CallableStatement cs = con.prepareCall("{call Genomics.INSERT_SEQUENCE (?,?,?,?,?,?,?,?,?)}"
cs.setString(1, nucSeqSingle.getComName());
cs.setString(2, nucSeqSingle.getOriginalDB());
cs.setString(3, nucSeqSingle.getCategory());
cs.setString(4, nucSeqSingle.getSubInd());
cs.setString(5, nucSeqSingle.getAccession());
cs.setString(6, nucSeqSingle.getAccVer());
cs.setInt (7, nucSeqSingle.getGi());
cs.setString(8, nucSeqSingle.getDescription());
cs.setString(9, nucSeqSingle.getSequence());
ResultSet rs = cs.executeQuery();
rs.next();
InsertionCodes insCodes = new InsertionCodes(rs.getInt(1), rs.getInt(2), rs.getString(3));
return insCodes;
}
catch (SQLException se) {
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
return null;
}
}
"Connection reset by peer: socket write error"
Among the data it parses are Strings, which often are concatenations weighing in at 300,000 characters long, and commonly longer.
Our highly-qualified and always-willing-to-help DBA informed me that the number of connections I've been maintaining with the database has varied between 2 and over 100(!). I am not doing any parallel processing, therefore, the maximum number of connections I'd ever expect at any given time should be 1. Another strange thing she told me is that when she runs a trace of the activity my computer is generating to the database, it shows many, many logons and logoffs, and not necessarily one at a time. For example, it might look like this: logon, logon, logon, logon, logoff, logoff, logon, etc...
It seems that for each SQL call a new connection is being created. Or perhaps the connections are never getting closed properly.
I've attached code from two of my classes below: DBConnection and InsertSequence. There is another class (not attached) that instantiates DBConnection (once per file parsed) and InsertSequence (once per record). Shouldn't the finalize method in InsertSequence (code below) be implicitly called to close all open connections?
We have been banging our head against the proverbial wall for quite a while here and it is really starting to hurt. Any help would be completely and totally appreciated!
RebLazer
Chicago, IL
********************
import java.sql.*;
public class DBConnection
{
public Connection con;
public DBConnection()
{
//constructor loads SQL DB Driver and sets up connection and statement objects
try
{
Class.forName(SSSConstants.driverClass);
}
catch(ClassNotFoundException e)
{
System.out.println("Unable to load Driver Class"
return;
}
try
{
//Create Connection
con = DriverManager.getConnection("jdbc:microsoft:sqlserver://10.3.55.117;selectMethod=cursor;programName=SSS_Parser", "reblazer", "reblazer1"
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
}
public void finalize()
{
try
{
//release resources upon exiting
con.close();
this.finalize();
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
}
/**
* Method to insert files that has been parsed from the database
* @param sqlString A variable of Type String. This is the Insert statement.
* @return res Returns variable of type boolean to indicate that rows have been inserted.
*/
public ResultSet insert(String sqlString)
{
ResultSet rs = null;
Statement sql = null;
try
{
//execute statement and return results
rs = sql.executeQuery(sqlString);
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
return rs;
}
/**
* Method to run query against DB for sequences that match user input
* @param sqlString A variable of Type String. This is the Select statement.
* @return rs This is the Resultset which is passed back to the calling program
*/
public ResultSet query(String sqlString)
{
ResultSet rs = null;//ResultSet is not needed but it must be set to null
try
{
//Create Statement
Statement sql = con.createStatement();
//execute statement and return results
rs = sql.executeQuery(sqlString);
}
catch (SQLException se)
{
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
return rs;
}
}
public class InsertSequence extends DBConnection
{
NucSeq nucSeqSingle;
public InsertSequence()
{
super();
}
public InsertionCodes checkAccession(NucSeq nucSeqSingle, DBConnection dbConn) {
try {
CallableStatement cs = con.prepareCall("{call Genomics.CHECK_SEQ_DATA (?,?,?,?,?,?,?,?)}"
cs.setString(1, nucSeqSingle.getComName());
cs.setString(2, nucSeqSingle.getOriginalDB());
cs.setString(3, nucSeqSingle.getCategory());
cs.setString(4, nucSeqSingle.getSubInd());
cs.setString(5, nucSeqSingle.getAccession());
cs.setString(6, nucSeqSingle.getAccVer());
cs.setInt (7, nucSeqSingle.getGi());
cs.setString(8, nucSeqSingle.getDescription());
ResultSet rs = cs.executeQuery();
rs.next();
InsertionCodes insCodes = new InsertionCodes(rs.getInt(2));
return insCodes;
}
catch (SQLException se) {
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
return null;
}
}
public InsertionCodes doInsert(NucSeq nucSeqSingle, DBConnection dbConn) {
try {
CallableStatement cs = con.prepareCall("{call Genomics.INSERT_SEQUENCE (?,?,?,?,?,?,?,?,?)}"
cs.setString(1, nucSeqSingle.getComName());
cs.setString(2, nucSeqSingle.getOriginalDB());
cs.setString(3, nucSeqSingle.getCategory());
cs.setString(4, nucSeqSingle.getSubInd());
cs.setString(5, nucSeqSingle.getAccession());
cs.setString(6, nucSeqSingle.getAccVer());
cs.setInt (7, nucSeqSingle.getGi());
cs.setString(8, nucSeqSingle.getDescription());
cs.setString(9, nucSeqSingle.getSequence());
ResultSet rs = cs.executeQuery();
rs.next();
InsertionCodes insCodes = new InsertionCodes(rs.getInt(1), rs.getInt(2), rs.getString(3));
return insCodes;
}
catch (SQLException se) {
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
return null;
}
}