Committing or rolling back DL/I transactions

The IMS Universal DL/I driver provides support for local transactions with the commit and rollback methods.

A local transaction consists of a unit of work with several units of recovery. A IMS Universal DL/I driver application can commit or roll back changes to the database within a unit of recovery. In the IMS Universal DL/I driver, the local transaction is scoped to the PSB instance. No explicit call is needed to begin a local transaction. A unit of work starts when the application allocates a PSB object and obtains a connection to the database by calling the PSB.allocate method.

After the unit of work starts, the application makes DL/I calls to access the database and create, replace, insert, or delete data. The application commits the current unit of recovery by using the PSB.commit method. The commit operation instructs the database to commit all changes to the database that are made from the point when the unit of work started, or from the point after the last commit or rollback method call, whichever was most recent.
Important: To persist changes made to the database, your application must call the commit method prior to deallocating the PSB, otherwise the changes are rolled back up to the last point the commit method was called.

The application can also end the unit of recovery by calling a roll back operation using the PSB.rollback method. Calling a roll back operation causes the database to undo all changes to the database made from the start of the unit of work, or from the point after the most recent commit or rollback call.

If the PSB.commit method or the PSB.rollback method is called and the PSB instance is not deallocated, a new unit of recovery is started. The overall unit of work ends when the PSB instance is deallocated. If the PSB.commit method or the PSB.rollback method are called while they are not currently in a unit of work (either before the PSB instance is allocated or after it is deallocated), an exception is thrown.

Local transaction with a single PSB

The following example code shows a local transaction for a single PSB.


IMSConnectionSpec connSpec = IMSConnectionSpecFactory.createIMSConnectionSpec();
connSpec.setDatastoreName("IMS1");
connSpec.setDatastoreServer("ecdev123.svl.ibm.com");
connSpec.setPortNumber(5555);
connSpec.setMetadataURL("class://BMP266.BMP266DatabaseView");
connSpec.setUser("usr");
connSpec.setPassword("password");
connSpec.setDriverType(IMSConnectionSpec.DRIVER_TYPE_4);        

PSB psb = PSBFactory.createPSB(connSpec);
psb.allocate(); // new unit of work begins
PCB pcb = psb.getPCB("PCb01");

SSAList ssa = pcb.getSSAList("HOSPITAL");
Path path = ssa.getPathForInsert("HOSPITAL");
path.setString("HOSPCODE", "R1210020000A");
path.setString("HOSPNAME", "SANTA TERESA");
pcb.insert(path);
psb.commit();	 // or use psb.rollback() to undo the insert.
              // The unit of receovery ends.

In this example, the application makes a connection to the database and allocates a PSB. The application obtains a PCB and specifies the path to insert a new HOSPITAL record. The application then performs a DL/I operation to insert the new record into the database. At this point, the application commits the insert operation and the new record is written to the database. Alternatively, the application can roll back the insert operation to return the database to the previous state before the insert call was made. This ends the current unit of recovery.

Local transaction with multiple PSBs

When two or more PSB objects are allocated by an application, separate local transactions for each PSB may run concurrently. The following example code shows multiple local transactions with two PSBs.


IMSConnectionSpec connSpec = IMSConnectionSpecFactory.createIMSConnectionSpec();
connSpec.setDatastoreName("IMS1");
connSpec.setDatastoreServer("ecdev123.svl.ibm.com");
connSpec.setPortNumber(5555);
connSpec.setMetadataURL("class://BMP266.BMP266DatabaseView");
connSpec.setUser("usr");
connSpec.setPassword("password");
connSpec.setDriverType(IMSConnectionSpec.DRIVER_TYPE_4);   

// create a connection to MyDB
PSB psb = PSBFactory.createPSB(connSpec);
psb.allocate(); // new unit of work begins for psb

// create another connection to MyDB.  
// Note: This does not need be be a connection to the same database. 
PSB psb2 = PSBFactory.createPSB(connSpec);
psb2.allocate(); 
 
pcb = psb.getPCB("PCb01");
SSAList ssa = pcb.getSSAList("HOSPITAL");
Path path = ssa.getPathForInsert("HOSPITAL");
path.setString("HOSPCODE", "R1210020000A");
path.setString("HOSPNAME", "SANTA TERESA");
pcb.insert(path);
psb.commit(); // or use psb.rollback() to undo the insert. 
              // The unit of recovery for psb ends

pcb2 = psb2.getPCB("PCb01");
SSAList ssa2 = pcb2.getSSAList("HOSPITAL");
Path path2 = ssa2.getPathForInsert("HOSPITAL");
path2.setString("HOSPCODE", "R1210010000A");
path2.setString("HOSPNAME", "ALEXANDRIA");
pcb2.insert(path2);
psb2.rollback(); //or use psb2.commit() to commit the insert.
                 // The unit of recovery for psb2 ends

psb2.deallocate(); // unit of work ends for psb2 
psb.deallocate(); // unit of work ends for psb 

In this example, the application makes two connections to the same database. A PSB is allocated for the first connection and the application performs a DL/I operation to insert a new HOSPITAL record with hospital name SANTA TERESA into the database. Another PSB is allocated to the second connection and an insert operation is made for a new HOSPITAL record with hospital name ALEXANDRIA. The application then commits the changes for the first PSB and writes the new record with hospital name SANTA TERESA to the database. The application issues a roll back statement for the second PSB, undoing the previous insert operation for the record with hospital name ALEXANDRIA. Only one new record is inserted to the database: the HOSPITAL record with hospital name SANTA TERESA.