Search code examples
db2websphere-libertyjsr352java-batch

In a (Liberty) Batch chunk step, getting "ResultSet is closed" when scrolling through ResultSet from database query issued earlier in the step


I am reading data from DB2 table and dumping it into a file.

I execute my simple select query in the chunk listener's beforeChunk() and use the step context to get it in itemreader.

In the chunk i set the checkpoint policy as item and itemcount as 5.

The output is the first 5 records being read and written over and over again.

In this sample java batch code from IBM's site they have start and end parameters in the query.

Is it necessary to have start and end parameters in your query? Is there no other way to make sure that when the query is run again it reads the next chunk of data and not the same chunk again and again?

I am using IBM's implementation of JSR 352 on WebSphere Liberty


Solution

  • Try configuring the datasource to use unshareable connections.

    If you are following this sample, you'll see it uses the older deployment descriptor XML files. You can edit batch-bonuspayout-application/src/main/webapp/WEB-INF/web.xml to add the line:

    <res-sharing-scope>Unshareable</res-sharing-scope>
    

    So in full you'd have:

    <web-app id="BonusPayout" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
      <display-name>BonusPayout</display-name>
      <description>This is the BonusPayout sample.</description>
      <resource-ref>
        <description>Bonus Payout DS</description>
        <res-ref-name>jdbc/BonusPayoutDS</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Unshareable</res-sharing-scope>
      </resource-ref>
    </web-app>
    

    This can also be done with the newer @Resource annotation, but if you've already switched to that then you'll know how to apply this point there too.

    With this change, the existing JNDI lookup at location: java:comp/env/jdbc/BonusPayoutDS will now use unshared connections, and the ResultSet will not be closed at the end of each chunk transaction.

    This behavior is indirectly documented here in the WebSphere Application Server traditional documentation. (I don't see it in the Liberty documentation, there are some cases like these where the behavior is basically identical in Liberty and the topic is not documented separately in Liberty.) It's a bit indirect for the batch user. Also it's hard to describe completely since as the doc says the exact behavior varies by DB and JDBC provider. But this should work for DB2.

    UPDATE: In newer (since 17.0.0.1) version of Liberty the unshareable connection can be obtained without needing to use a resource reference by configuring the connectionManager using the enableSharingForDirectLookups attribute, e.g.:

    <connectionManager ...  enableSharingForDirectLookups="false"/>