Developing JBP applications with the IMS Java dependent region resource adapter

JBP applications are similar to JMP applications, except that JBP applications do not receive input messages from the IMS message queue. Unlike batch message processing (BMP) applications, JBP applications must be non-message-driven applications.

Symbolic checkpoint and restart

Similarly to batch message processing (BMP) applications, JBP applications can use symbolic checkpoint and restart calls to restart the application after an abend. To issue a symbolic checkpoint and restart when using the IMS Java dependent region resource adapter, use these methods of the com.ibm.ims.dli.tm.Transaction interface:

  • Transaction.checkpoint()
  • Transaction.restart()

These methods perform functions that are analogous to the DL/I system service calls: (symbolic) CHKP and XRST.

A JBP application connects to a database, makes a restart call, performs database processing, periodically checkpoints, and disconnects from the database at the end of the program. The program must issue a final commit before ending. On an initial application start, the Transaction.restart() method notifies IMS that symbolic checkpoint and restart is to be enabled for the application. The application then issues periodic Transaction.checkpoint() calls to take checkpoints. The Transaction.checkpoint() method allows the application to provide a com.ibm.ims.dli.tm.SaveArea object that contains one or more other application Java objects whose state is to be saved with the checkpoint.

If a restart is required, it defaults to the last checkpoint ID. The Transaction.restart() method returns a SaveArea object that contains the application objects in the same order in which they were inserted at checkpoint time. If the SaveArea object returned is null, this means there were no objects stored in the SaveArea object at checkpoint time.

Symbolic checkpoint and restart calls may also be used with GSAM data, or z/OS® data sets. To restart using a basic z/OS checkpoint, you must identify the restart checkpoint.

Code sample of JBP symbolic checkpoint and restart

The following symbolic checkpoint/restart sample JBP application demonstrates the use of the checkpoint and restart functionality support with the IMS Java dependent region resource adapter.

The two symbolic checkpoint methods checkpoint() andcheckpoint(SaveArea saveArea) require the application to be restarted (in the case of any abnormal end of the program) using the 4-character constant LAST.

package samples.dealership.chkp_xrst;

import java.sql.*;
import java.io.*;

import com.ibm.ims.dli.DLIException;
import com.ibm.ims.dli.tm.Application;
import com.ibm.ims.dli.tm.ApplicationFactory;
import com.ibm.ims.dli.tm.SaveArea;
import com.ibm.ims.dli.tm.Transaction;
import com.ibm.ims.jdbc.IMSDataSource;

public class CheckpointRestartAutoSample {

    private SaveArea saveAreaOut;
    private Connection connection;
    private Transaction transaction;

    // The entry point of the application
    public static void main(String[] args) throws Exception {
        CheckpointRestartAutoSample crSample 
          = new CheckpointRestartAutoSample();

        crSample.setup();

        crSample.runSample();

        crSample.closeDown();

    }

    // Set up for the application: 
    //  1. Enable trace
    //  2. Creates connection
    void setup() throws Exception {
        this.createConnection();
        Application app = ApplicationFactory.createApplication();
        this.transaction = app.getTransaction();
    }

    void closeDown() throws Exception {
        // close the connection
        connection.close();

        // Commit the IMS DB work
        this.transaction.commit();
    }

    // Creates a connection to the auto dealership database
    void createConnection() throws Exception {
        try {
            IMSDataSource ds = new IMSDataSource();
         ds.setDriverType(IMSDataSource.DRIVER_TYPE_2);
         ds.setMetadataURL("class://samples.dealership.AUTPSB11DatabaseView");

            connection = ds.getConnection();

        } catch (SQLException e) {
            String errorMessage 
               = new String("During connection creation: " 
                   + e.toString());
            throw new Exception(errorMessage);
        }
    }

    void runSample() throws Exception {
        // the restart call is always the first call in a  
        // checkpoint/restart application
        saveAreaOut = this.transaction.restart();

        // if the SaveArea object returned is null it  
        // is a normal program start, otherwise it is a restart 
        if (saveAreaOut != null) {
            // Check the SaveArea object to determine 
               // where to restart from
            if (saveAreaOut.isEmpty()) {
                sqlMethod(true);
            } else {
                String str = 
                   (String)saveAreaOut.getObject(1);
                System.out.println("Retrieved string = "+str);
            }
        } else {
            sqlMethod(false);
        }
    }

    void sqlMethod(boolean isRestart) 
       throws DLIException, SQLException {

        String sql 
          = new String("SELECT * FROM Dealer.DealerSegment");
        Statement statement = connection.createStatement();
        ResultSet results = statement.executeQuery(sql);

        // this part of the code will be executed only during a normal
        // program start
        if (!isRestart && results.next()) {
            System.out.println("At first GetSegment call to the DealerDB: ");
            System.out.println("Dealer Number = " 
               + results.getString("DealerNo"));
            System.out.println("Dealer Name   = " 
               + results.getString("DealerName"));
            System.out.println("DealerCity    = " 
               + results.getString("DealerCity"));
            System.out.println("DealerZip     = " 
               + results.getString("DealerZip"));
            System.out.println("DealerPhone   = " 
               + results.getString("DealerPhone"));
        }

        //String ckptid = null;
        for (int i=1; results.next(); i++) {
            System.out.println("GetSegment call to the DealerDB:");
            System.out.println("Dealer Number = " 
               + results.getString("DealerNo"));
            System.out.println("Dealer Name   = " 
               + results.getString("DealerName"));
            System.out.println("DealerCity    = " 
               + results.getString("DealerCity"));
            System.out.println("DealerZip     = " 
               + results.getString("DealerZip"));
            System.out.println("DealerPhone   = " 
               + results.getString("DealerPhone"));

       // The checkpoint call, apart from storing program information, 
       // causes the program to lose its position in the database
            this.transaction.checkpoint();
        }
    }

}

Rolling back changes in a JBP application

Similar to JMP applications, a JBP application can roll back database processing and output messages any number of times during a transaction. A rollback call backs out all database processing and output messages to the most recent commit.

Use the com.ibm.ims.dli.tm.Transaction class to issue commit and rollback operations from your JMP application.