0

This is my first time trying to read and write to a VSAM file. What I did was:

  1. Created a Map for the File using VSE Navigator
  2. Added the Java beans VSE Connector library to my eclipse Java project
  3. Use the code show below to Write and Read to the KSDS file.

Reading the file is not a problem but when I tried to write to the file it only works if I go on the mainframe and close the File before running my java program but it locks the file for like an hour. You cannot open the file on the mainframe or do anything to it.

Anybody can help with this problem. Is there a special setting that I need to set up for the file on the mainframe ? Why do you first need to close the file on CICS to be able to write to it ? And why does it locks the file after writing to it ?

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.*;
public class testVSAM {

public static void main(String argv[]){
    Integer test = Integer.valueOf(2893);
    String vsamCatalog = "VSESP.USER.CATALOG";
    String FlightCluster = "FLIGHT.ORDERING.FLIGHTS";       
    String FlightMapName = "FLIGHT.TEST2.MAP";
    try{

        String ipAddr = "10.1.1.1";                     
        String userID = "USER1";            
        String password = "PASSWORD"; 

        java.sql.Connection jdbcCon;            
        java.sql.Driver jdbcDriver = (java.sql.Driver) Class.forName(
        "com.ibm.vse.jdbc.VsamJdbcDriver").newInstance();
        // Build the URL to use to connect
        String url = "jdbc:vsam:"+ipAddr;
        // Assign properties for the driver
        java.util.Properties prop = new java.util.Properties();
        prop.put("port", test);
        prop.put("user", userID);
        prop.put("password", password);
        // Connect to the driver
        jdbcCon = DriverManager.getConnection(url,prop);

        try {
            java.sql.PreparedStatement pstmt = jdbcCon.prepareStatement(
            "INSERT INTO "+vsamCatalog+"\\"+FlightCluster+"\\"+FlightMapName+
            " (RS_SERIAL1,RS_SERIAL2,RS_QTY1,RS_QTY2,RS_UPDATE,RS_UPTIME,RS_EMPNO,RS_PRINTFLAG,"+
            "RS_PART_S,RS_PART_IN_A_P,RS_FILLER)"+" VALUES(?,?,?,?,?,?,?,?,?,?,?)");
            //pstmt.setString(1, "12345678901234567890123003");
            pstmt.setString(1, "1234567890");
            pstmt.setString(2,"1234567890123");
            pstmt.setInt(3,00);
            pstmt.setInt(4,003);
            pstmt.setString(5,"151209");
            pstmt.setString(6, "094435");
            pstmt.setString(7,"09932");
            pstmt.setString(8,"P");
            pstmt.setString(9,"Y");
            pstmt.setString(10,"Y");
            pstmt.setString(11," ");
            // Execute the query
            int num = pstmt.executeUpdate();
            System.out.println(num);
            pstmt.close();

            }
            catch (SQLException t)
            {

                System.out.println(t.toString());                       
            } 

        try
        {
        // Get a statement
        java.sql.Statement stmt = jdbcCon.createStatement();
        // Execute the query ...
        java.sql.ResultSet rs = stmt.executeQuery(
        "SELECT * FROM "+vsamCatalog+"\\"+FlightCluster+"\\"+FlightMapName);

        while (rs.next())
        {                                           
        System.out.println(rs.getString("RS_SERIAL1") +  " " + rs.getString("RS_SERIAL2")+  " " + rs.getString("RS_UPTIME")+ " " + rs.getString("RS_UPDATE"));
        }
        rs.close();
        stmt.close();
        }
        catch (SQLException t)
        {

        } 
    }
    catch (Exception e)
    {
        // do something appropriate with the exception, *at least*:
        e.printStackTrace();
    } 

}

}

Note: the OS is z/VSE

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
CodeEngine
  • 296
  • 1
  • 9
  • 28
  • So your question is what exactly? Why writing to a file needs exclusive lock? Why write takes so long? Please try to be more specific. – Jan Dec 10 '15 at 15:35
  • I updated my question. But my question would be. Why do I need to first close the file on CICS to be able to Write to the file. And why the file locks (cannot open, read or write) after I write to the file ? – CodeEngine Dec 10 '15 at 15:53
  • for one I don't see you closing your connection into that file - that might keep it open and locked. – Jan Dec 10 '15 at 15:59
  • Jan thanks for the help! :).We fix this issue. The problem was that the VSE connector on the server side(mainframe) which is used by JDBC uses a batch program. The CISC file was created with the option that only CICS programs could write to it and not batch programs. We redefine the file with the property that batch programs can write to it and now it works. I'm a PC programmer so sorry if the terminology or explanation is not the best about the mainframe. – CodeEngine Dec 10 '15 at 16:10
  • 2
    It would be good if you took the time and answered your own question (and accept it!) So the next person has some info on how to.fix this by searching. – Jan Dec 10 '15 at 16:15
  • Ok I am going to ! thanks ! – CodeEngine Dec 10 '15 at 16:32

2 Answers2

2

The short answer to your original question is that KSDS VSAM is not a DBMS.

As you have discovered, you can define the VSAM file such that you can update it both from batch and from CICS, but as @BillWoodger points out, you must serialize your updates yourself.

Another approach would be to do all updates from the CICS region, and have your Java application send a REST or SOAP or MQ message to CICS to request its updates. This does require there be a CICS program to catch the requests from the Java application and perform the updates.

cschneid
  • 10,237
  • 1
  • 28
  • 39
0

The IBM Mainframe under z/VSE has different partitions that run different jobs. For example partition F7 CICS, partition F8 Batch Jobs, ETC.

When you define a new VSAM file you have to set the SHAREOPTIONS of the file. When I define the file I set the SHAREOPTIONS (2 3). 2 Means that only one partition can write to the file.

So when the batch program (in a different partition to the CICS partition) which is called from Java was trying to write to the file it was not able to write to the file unless I close the file in CICS first.

To fix it I REDEFINE the CICS file with SHAREOPTIONS (4 3). 4 Means that multiple partitions of the Mainframe can write to it. Fixing the problem

Below is a part of the definition code where you set the SHAREOPTION:

* $$ JOB JNM=DEFFI,CLASS=9,DISP=D,PRI=9         
* $$ LST CLASS=X,DISP=H,PRI=2,REMOTE=0,USER=JAVI
// JOB DEFFI                                    
// EXEC IDCAMS,SIZE=AUTO                                                         
DEFINE  CLUSTER -                            
          ( -                                
          NAME (FLIGHT.ORDERING.FLIGHTS) -  
          RECORDS (2000 1000) -              
          INDEXED -                          
          KEYS (26 0) -                      
          RECORDSIZE (128 128) -             
          SHAREOPTIONS (4 3) -               
          VOLUMES (SYSWKE) -                 
          ) -                                
          .
          .  
          .              
Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
CodeEngine
  • 296
  • 1
  • 9
  • 28
  • 2
    Slow down: "With options 3 and 4 you are responsible for maintaining both read and write integrity for the data the program accesses. These options require your program to use ENQ/DEQ to maintain data integrity while sharing the data set, including the OPEN and CLOSE processing. User programs that ignore the write integrity guidelines can cause VSAM program checks, lost or inaccessible records, uncorrectable data set failures, and other unpredictable results. These options place heavy responsibility on each user sharing the data set." – Bill Woodger Dec 10 '15 at 18:58
  • Hey Bill, I should have mention that I am a PC Programmer and not a Mainframe programmer. When you talk about my program to use ENQ/DEQ are you talking about a CISC program that reads/writes to the VSAM file ? – CodeEngine Dec 10 '15 at 19:15
  • 1
    If two "programs" have update access to the same file they need to have code to ENQue the resource, do the work, then DEQueue the resource. Else at best you'll lose data from time-to-time, at worst you'll damage the file beyond repair. Sending messages from your Java to a CICS (note the order of the letters) program to do the updates is one way to keep things simple. Note also you may/will have reduced performance with SHAREOPTIONS 3 or 4, even for simply reading the file. – Bill Woodger Dec 10 '15 at 19:21
  • 1
    For someone new to the Mainframe, you need to rely on your Mainframe colleagues and Technical Support. They'll bounce this quick as anything, so you'll need a different solution anyway. So in the design somewhere this should have been covered. If you want to do multiple simultaneous updates from different "programs" (using the term loosely, considering CICS a program) then you need to deal with it in both/all programs. – Bill Woodger Dec 10 '15 at 19:23
  • 1
    SHAREOPTIONS 4 facilitates multiple updates, but data-integrity is down to the user (programmer). – Bill Woodger Dec 10 '15 at 19:25
  • And don't worry about being a beginner on this. Even people with many years of experience haven't used 4. Not for the faint-hearted. – Bill Woodger Dec 10 '15 at 19:26
  • I'm researching about ENQ/DEQ so this is code that you write on PL1 or COBOL, etc on CICS to handle the VSAM file when is being access by different "Programs" ? Is this correct ? Thanks for the comments and taking the time to explain this issue ! – CodeEngine Dec 10 '15 at 19:37
  • Not COBOL. Possibly PL/I. For sure Assembler. However, do you want to do all that if you can just pass a message to CICS and have the thing which processes the message within CICS do the updates? – Bill Woodger Dec 10 '15 at 21:18