0

I create a Connection Connection con = ds.getConnection();(where ds is DataSource) in the open of the Reader and close it in the close() of the Reader.

But when i run a job with multiple partitions, in the middle of the job , i get Connection is closed error

Caused by: java.sql.SQLException: [jcc][t4][10335][10366][3.58.82] Invalid operation: Connection is closed. ERRORCODE=-4470, SQLSTATE=08003 DSRA0010E: SQL State = 08003, Error Code = -4,470

I assume this happens when one of the partition completes.

So my question is why does this happen? And how should connections be handled? Or does Java take care of closing the connections?

I am using Java Batch on WebSphere Liberty UPDATE:

<jdbcDriver libraryRef="DB2JCC4Lib"/>

<properties.db2.jcc databaseName="" driverType="4" password="" portNumber="" queryDataSize="65535" serverName="" user=""/>

</dataSource>




public class Reader implements ItemReader {
private DataSource ds = null;
private Connection con = null;
public Reader() {

}

public void close() {
    try {
        con.close();
        rs.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }

}

/**
 * @see ItemReader#readItem()
 */
public Object readItem() {
    String s="";
    try {
    if (rs.next()) {
                for (int i = 1; i <= 10; i++) {
                    s+=rs.getString(i);                     
                }
                return s;
            }
         else {
            return null;
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}
public Serializable checkpointInfo() {

}

public void open(Serializable checkpoint) {

    if (ds == null) {
        try {
            ds = (DataSource) new InitialContext()
                    .lookup("java:comp/env/jdbc/dataSource");
        } catch (Exception e) {
        e.printStackTrace();
        }
    }

    try {
        con = ds.getConnection();
        statement= con
                .prepareCall("call abc.xyz(?)");
        statement.setString("param", "xxx");
        boolean result= statement.execute();
        if (result) {
            rs = statement.getResultSet();
            if (rs == null) {
                throw new NullPointerException();
            }               
        } else {
            throw new SQLException();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

Complete error message [ERROR ] J2CA0024E: Method rollback, within transaction branch ID {XidImpl: formatId(57415344), gtrid_length(36), bqual_length(40), data(0000015645eff4470000000915937ff85f46c3ed056b19010aa5147e1183f8d3ae81c04c0000015645eff4470000000915937ff85f46c3ed056b19010aa5147e1183f8d3ae81c04c00000001)} of resource pool connectionManager[Pool], caught com.ibm.ws.exception.WsException: DSRA0080E: An exception was received by the Data Store Adapter. See original exception message: [jcc][t4][10335][10366][3.58.82] Invalid operation: Connection is closed. ERRORCODE=-4470, SQLSTATE=08003. with SQL State : 08003 SQL Code : -4470

Fazil Hussain
  • 425
  • 3
  • 16
  • 1
    Can you post some sample code illustrating your use of the Connection and ResultSet? You aren't sharing across threads are you? Can you also show your DataSource / JDBC config from server.xml and also mention whether you're using the "unshared connections" approach mentioned in [this question](http://stackoverflow.com/questions/36935252/in-a-liberty-batch-chunk-step-getting-resultset-is-closed-when-scrolling-th#). – Scott Kurz Jul 22 '16 at 13:51
  • Yes i am using the Unshared Connections approach. The problem happens only when i close the connection in close(). If i remove it, it works fine. – Fazil Hussain Aug 01 '16 at 09:54
  • You're closing the Connection before the ResultSet. You should close the ResultSet first. – Scott Kurz Aug 01 '16 at 11:37
  • I tried again, closing the connection after closing the result set. But i still get the same error. The error occurs in readItem() and is caught by the catch in readItem(). I have added the complete error message – Fazil Hussain Aug 01 '16 at 11:59
  • You didn't show it but I assume `con` is just a field / instance variable? – Scott Kurz Aug 01 '16 at 14:18
  • Yes private DataSource ds = null; private Connection con = null; are instance variables – Fazil Hussain Aug 01 '16 at 14:25

1 Answers1

0

I dont't know if JSR-352's Batch handles processing exactly the same way as Spring Batch does but...

In Spring Batch if you have a Reader that uses chunk processing what i think you could do to solve the problem is to put the openConnection() in the beforeRead() and the closeConnection() in the afterRead().

To do that you should implement a Listener. Check these out so you get an idea of what i'm talking about.

Spring Annotation Type BeforeRead

Interface ItemReadListener

Julian
  • 344
  • 1
  • 11