Sie sind auf Seite 1von 362

Front cover

DB2 for z/OS and WebSphere: re: The Perfect Couple uple
Configure the DB2 Universal Driver with WebSphere Application Server for z/OS Using SQLJ within WebSphere Studio Application Developer Sample application showing SQLJ support for CMP EJBs

Bart Steegmans Carsten Block John De Dominicis Sean Lee Chao-Lin Liu Egide Van Aerschot

ibm.com/redbooks

International Technical Support Organization DB2 for z/OS and WebSphere: The Perfect Couple January 2005

SG24-6319-00

Note: Before using this information and the product it supports, read the information in Notices on page xix.

First Edition (January 2005) This edition applies to Version 7 of DB2 for z/OS and OS/390 (product number 5675-DB2), DB2 for z/OS Version 8 (product number 5625-DB2), and WebSphere Application Server for z/OS Version 5.02 (product number 5655-I35).
Copyright International Business Machines Corporation 2005. All rights reserved. Note to U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

Contents
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ix Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xx Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi The team that wrote this redbook. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii Chapter 1. Introduction to DB2 for z/OS and OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Relational database management systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 The DB2 Universal Database Family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2.1 DB2 UDB for Linux, UNIX, and Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2.2 DB2 UDB for iSeries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2.3 DB2 Server for VSE and VM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2.4 More information on the DB2 UDB family, related tools, and products. . . . . . . . . . 4 1.3 Components of DB2 UDB for z/OS and OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3.1 DB2 UDB for z/OS and OS/390 address spaces . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.3.2 DB2 attachment facilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.4 DB2 data structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.4.1 Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.4.2 Storage groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.3 Data sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.4 Table spaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.5 Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.4.6 Indexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.5 Structured query language (SQL) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.5.1 Static SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.5.2 Dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.5.3 Industry standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.6 DB2 concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.6.1 Referential constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.6.2 DB2 packages, plans, collections, and package lists . . . . . . . . . . . . . . . . . . . . . . 17 1.6.3 Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.7 Accessing DB2 from a Java environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.7.1 JDBC fundamentals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.7.2 JDBC driver types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 1.7.3 IBM DB2 Legacy Driver. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.8 IBM DB2 Universal Driver for SQLJ and JDBC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.8.1 IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 . . . . . . . . . . . . . 24 1.9 Using the DB2 Universal Driver for SQLJ and JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1.9.1 Required environment variable settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1.9.2 DB2 Universal Driver stored procedures and metadata . . . . . . . . . . . . . . . . . . . . 28 1.9.3 Binding DB2 Universal JDBC Driver packages with the DB2Binder utility . . . . . . 29

Copyright IBM Corp. 2005. All rights reserved.

iii

1.9.4 DB2T4XAIndoubtUtil utility for DB2 UDB for OS/390 and z/OS Version 7 . . . . . . 30 1.9.5 Differences between the DB2 Universal Driver and DB2 Legacy Driver. . . . . . . . 31 1.9.6 JDBC 3.0 APIs specific to the DB2 Universal Driver. . . . . . . . . . . . . . . . . . . . . . . 32 Chapter 2. Introduction to WebSphere for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 Java 2 Enterprise Edition (J2EE) overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 WebSphere Application Server architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 WebSphere Application Server administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 Administration console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Other tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 The WebSphere family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 WAS 5.0.2 features and J2EE support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 3. WebSphere - DB2 environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Introduction to the sample scenario setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Introduction to DB2 drivers for Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Data source definitions in WAS V5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 The IBM DB2 Universal Driver for SQLJ and JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Summary of WAS z/OS external changes for the Universal Driver . . . . . . . . . . . 3.5 Configuring Universal JDBC Driver type 2 connectivity . . . . . . . . . . . . . . . . . . . . . . . . 3.5.1 Specifying the Universal JDBC Driver provider. . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.2 Defining Data Sources under this provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.3 Setting/verifying the symbolic environment variables . . . . . . . . . . . . . . . . . . . . . . 3.5.4 Defining DB2 Universal Driver - General properties . . . . . . . . . . . . . . . . . . . . . . . 3.5.5 Searching for the package to execute . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.6 Linking to the DB2 libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.7 Creating a new Application Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 Configuring Universal JDBC Driver type 4 connectivity . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1 Using the Universal Driver for type 4 (non-XA) . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.2 Using the Universal Driver for type 4 (XA) connectivity . . . . . . . . . . . . . . . . . . . . 3.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 36 40 44 45 46 47 48 49 50 50 51 52 52 53 54 57 64 65 68 70 73 78 79 80 88

Chapter 4. DB2 and Java architecture guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4.1 Introduction to J2EE data access architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.2 Servlets and JavaServer Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.2.1 Benefits of data access from servlets and JSPs . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.2.2 Considerations for data access from a servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.3 Enterprise JavaBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.4 Session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.5 Stateless session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 4.5.1 Benefits of data access from a stateless session Bean . . . . . . . . . . . . . . . . . . . . 94 4.5.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4.6 Stateful session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4.6.1 Benefits of stateful session Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4.6.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4.7 Entity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.8 Bean-Managed Persistence entity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.8.1 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.8.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.9 Container-Managed Persistence entity Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.9.1 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.9.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 4.10 Message-driven Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 4.11 Session facade pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 iv
DB2 for z/OS and WebSphere: The Perfect Couple

4.12 Stored procedures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.12.1 Benefits of accessing data from stored procedures . . . . . . . . . . . . . . . . . . . . . 4.12.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.13 Web services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.14 SQLJ support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.15 Java Data Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.16 EJB Beans summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 5. DB2 application development in a WebSphere environment . . . . . . . . . . 5.1 JDBC and SQLJ application programming comparison . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 JDBC and SQLJ compared. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.2 Best practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 JDBC application programming concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 Java packages for JDBC applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.2 Using the DB2 Universal JDBC Driver and the DataSource interface . . . . . . . . 5.2.3 Java identifiers and JDBC parameter markers . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.4 Statement and ResultSet interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 SQLJ application programming concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4 Preparing JDBC and SQLJ applications for execution . . . . . . . . . . . . . . . . . . . . . . . . 5.4.1 JDBC program preparation process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4.2 SQLJ program preparation process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5 Impact of different DB2 bind options on Java applications . . . . . . . . . . . . . . . . . . . . . 5.5.1 OWNER bind option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5.2 QUALIFIER bind option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5.3 DYNAMICRULES bind option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.5.4 ISOLATION bind option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6 Special registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.1 CURRENT SQLID. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.2 CURRENT SCHEMA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.3 CURRENT PACKAGESET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.4 CURRENT PACKAGE PATH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6.5 Using properties to specify special registers. . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 6. WebSphere - DB2 security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1 Introduction to authentication, authorization, and auditing . . . . . . . . . . . . . . . . . . . . . 6.1.1 Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.2 Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.3 Auditing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.4 Application or infrastructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.5 DB2-supported authentication, authorization, and auditing . . . . . . . . . . . . . . . . 6.1.6 Choosing what identity to send DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.7 Configuring WebSphere for authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.8 Programmatic authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.9 Default user ID and password authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.10 Thread identity support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 DB2 auditing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7. SQLJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1 Writing SQLJ versus JDBC applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.1 Connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.2 Using SQLJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.3 Using JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Profile customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2.1 Profile customization when using unqualified SQL . . . . . . . . . . . . . . . . . . . . . . .
Contents

102 102 103 104 104 104 105 109 110 110 111 112 113 113 114 114 116 116 117 117 120 120 120 120 121 121 121 122 123 124 124 127 128 128 128 128 129 129 130 131 135 135 135 136 139 140 140 144 146 146 148 v

7.2.2 Reducing the number of SQLJ-generated packages . . . . . . . . . . . . . . . . . . . . . 7.2.3 Using manual package versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3 Application design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.1 Best practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.2 The detailed application flow. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.3 Exceptions and transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.4 SQL exceptions and SQL warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4 SQLJ in WebSphere Studio Application Developer . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.1 Setting up the environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.2 Create the server and the datasource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.3 Using an SQLJ Java project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.4 User-managed persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.5 Container-managed persistence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.6 Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.7 WAS 5.1.0.1 FixPak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.5 Deployment to WebSphere Application Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 8. Transaction management in a WebSphere environment . . . . . . . . . . . . . 8.1 What transactions are . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 Local transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.2 Global transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2 WebSphere transaction management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2.1 Transaction demarcation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2.2 Bean-managed transactions and the UserTransaction interface . . . . . . . . . . . . 8.2.3 Transaction types (for container-managed transactions) . . . . . . . . . . . . . . . . . . 8.3 WebSphere resources and transaction support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.1 Resource interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.2 Resource transaction isolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.3 Configuring JDBC resources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.4 DB2 as a transaction manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.4.1 Configuring and exploiting DB2 as a transaction manager . . . . . . . . . . . . . . . . . 8.4.2 DB2 configuration requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.4.3 DB2 or WAS as a transaction manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5 DB2 as a resource manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.1 DB2s support for XA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.2 Global transaction support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6 Considerations for two-phase commit processing. . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6.1 Lock duration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6.2 Failure impact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6.3 Lock impact from failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.6.4 How to recover from failures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 9. DB2 locking in a WebSphere environment . . . . . . . . . . . . . . . . . . . . . . . . . 9.1 DB2 locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Transaction isolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.1 Isolation levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.2 Overriding lock mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.3 DB2 isolation determination in Java applications . . . . . . . . . . . . . . . . . . . . . . . . 9.2.4 Maintaining integrity with isolation Cursor Stability . . . . . . . . . . . . . . . . . . . . . . . 9.2.5 Data sharing considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3 WebSphere transaction-related deployment descriptors . . . . . . . . . . . . . . . . . . . . . . 9.3.1 Setting the WebSphere transaction isolation level . . . . . . . . . . . . . . . . . . . . . . .

149 149 150 150 153 154 158 159 160 161 167 172 183 187 188 189 190 191 192 192 192 194 194 195 196 198 198 199 199 202 202 203 204 204 204 205 206 206 207 207 207 209 210 210 212 212 213 214 216 217 217

vi

DB2 for z/OS and WebSphere: The Perfect Couple

9.3.2 Entity Bean isolation level (access intent). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4 Container-managed persistence generated SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4.1 Who generates the persistence SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4.2 Access intents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 10. DB2 - WebSphere performance aspects. . . . . . . . . . . . . . . . . . . . . . . . . . 10.1 Recommended hardware and software configuration. . . . . . . . . . . . . . . . . . . . . . . . 10.2 WebSphere Application Server connection pooling . . . . . . . . . . . . . . . . . . . . . . . . . 10.2.1 What is new in Version 5 - What is in WebSphere Version 4 . . . . . . . . . . . . . . 10.2.2 How connection pooling works - How connection objects are structured . . . . . 10.2.3 WebSphere data sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2.4 Connection pooling - Best practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3 DB2 and JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.1 Adjusting the number of DB2 threads and connections . . . . . . . . . . . . . . . . . . 10.3.2 Enabling DB2 dynamic statement cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.3 Choosing static SQL over dynamic SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.4 Usage guidelines for JCC type 2 and type 4 connectivity . . . . . . . . . . . . . . . . . 10.3.5 Enterprise JavaBeans (EJBs) and DB2 access . . . . . . . . . . . . . . . . . . . . . . . . 10.4 WLM classification of WAS and its impact on DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.1 How DB2 and WebSphere Servers are structured on z/OS . . . . . . . . . . . . . . . 10.4.2 Enabling WLM dynamic application environments with WAS V5 . . . . . . . . . . . 10.4.3 WebSphere classification and its impact on DB2 . . . . . . . . . . . . . . . . . . . . . . . 10.5 Tuning the storage for z/OS and the Java Virtual Machine. . . . . . . . . . . . . . . . . . . . 10.6 Universal Driver tracing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.6.1 Universal Driver tracing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.6.2 DB2SystemMonitor class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 11. Sample application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.1 Sample table description. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.2 Importing the tables into WSAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 MVC model with entity Beans and a session Bean. . . . . . . . . . . . . . . . . . . . . . . . . . 11.2.1 Creating entity CMP Beans using JDBC from the imported tables . . . . . . . . . . 11.2.2 Container-managed persistence entity Beans with SQLJ. . . . . . . . . . . . . . . . . 11.2.3 Bean and container-managed persistence entity Bean with SQLJ . . . . . . . . . . 11.2.4 Bean-managed persistence entity Beans with JDBC . . . . . . . . . . . . . . . . . . . . 11.2.5 Completing the model with the session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 The View component of the MVC model. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.4 Controller component of MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.5 The enterprise J2EE application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.6 Deployment of the EAR file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.7 Test of the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

218 218 219 219 221 222 222 223 223 224 228 229 229 229 230 230 232 232 233 233 233 234 235 235 244 245 246 248 249 253 253 273 280 280 290 296 298 306 307 313

. Appendixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Appendix A. Additional material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Locating the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . How to use the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 319 319 319 321 321 321 322

Contents

vii

How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 Help from IBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323

viii

DB2 for z/OS and WebSphere: The Perfect Couple

Figures
1-1 1-2 1-3 1-4 1-5 1-6 1-7 2-1 2-2 2-3 2-4 2-5 2-6 2-7 2-8 2-9 2-10 2-11 2-12 3-1 3-2 3-3 3-4 3-5 3-6 3-7 3-8 3-9 3-10 3-11 3-12 3-13 3-14 3-15 3-16 3-17 3-18 3-19 3-20 3-21 3-22 3-23 3-24 3-25 3-26 3-27 3-28 3-29 Basic data flow in a DB2 subsystem from z/OS and distributed environments . . . . . . 8 DB2 data structure hierarchy and relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Different types of table spaces available in DB2 UDB for OS/390 and z/OS. . . . . . . 11 Referential constraints between tables DEPT and EMP . . . . . . . . . . . . . . . . . . . . . . 17 Program preparation using the DB2 precompiler or SQL statement coprocessor. . . 18 IBM DB2 Universal JDBC Driver type 2 and type 4 connectivity . . . . . . . . . . . . . . . . 23 DB2 z/OS Application Connectivity and DB2 Universal Driver implementations . . . . 25 J2EE architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 J2EE roles with an IBM perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Content of the EAR file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 WebSphere as a HTTP server plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Controllers and servants, the server instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Base Application Server node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Multiple Base Application Server nodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 One Base Application Server node with multiple servers . . . . . . . . . . . . . . . . . . . . . 43 Two-system sysplex, deployment manager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Administrative Console login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Administrative Console home page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 The WebSphere pyramid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Configuration used in our sample scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Type 2 drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Login screen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 Admin console after login. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 Available JDBC providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 List of available JDBC providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Driver properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 JDBC new provider list. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Additional properties of the DB2 Universal JDBC Driver Provider. . . . . . . . . . . . . . . 57 New Data Source. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 General Properties 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 General Properties 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 General Properties 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Additional Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Custom Properties 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 Custom Properties 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Custom Properties 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Custom Properties 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 WebSphere Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Symbolic parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Application Server selection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Servant selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Additional properties under Process Definition/Servant. . . . . . . . . . . . . . . . . . . . . . . 67 Custom Properties under Servant/Java Virtual Machine . . . . . . . . . . . . . . . . . . . . . . 68 New property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Start command and arguments for Servant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Environment entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 New environment entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 Adding the STEPLIB variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Copyright IBM Corp. 2005. All rights reserved.

ix

3-30 3-31 3-32 3-33 3-34 3-35 3-36 3-37 3-38 3-39 3-40 3-41 3-42 3-43 3-44 3-45 3-46 5-1 5-2 5-3 5-4 5-5 6-1 6-2 6-3 6-4 6-5 6-6 7-1 7-2 7-3 7-4 7-5 7-6 7-7 7-8 7-9 7-10 7-11 7-12 7-13 7-14 7-15 7-16 7-17 7-18 7-19 7-20 7-21 7-22 7-23 7-24 8-1 x

Select Application Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Create a new server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Create new Application Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Overview with new Application Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Configuration hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Overview of Application Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 Configuration of new server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 type 4 driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Create new JDBC provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 JDBC Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Configuration for XA JDBC provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 Manage WebSphere Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 DB2 Universal JDBC Driver (XA). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 New Data Source type 4 definition to DBD8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 Custom Properties selection for the Data Source . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Properties for a type 4 Data Source different from type 2 . . . . . . . . . . . . . . . . . . . . . 86 Properties for a type 4 Data Source different from type 2 . . . . . . . . . . . . . . . . . . . . . 87 SQLJ program preparation using the DB2 JDBC Legacy Driver . . . . . . . . . . . . . . . 118 SQLJ program preparation process using the DB2 Universal JDBC Driver . . . . . . 119 Setting the currentSQLID property. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Setting the currentSchema property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 Setting the currentPackageSet property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Adding the securityMechanism property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 Specifying a Beans Run-As value. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 Setting the Res-Auth value within an EJB reference to a datasource . . . . . . . . . . . 134 Setting JCA user identity and password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 Setting the container and component JCA identities . . . . . . . . . . . . . . . . . . . . . . . . 135 Enabling Sync To OS thread support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 The SQLJ roadmap from the client container to DB2 . . . . . . . . . . . . . . . . . . . . . . . 150 Best practice overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Application flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Setting the transaction type in WebSphere Studio Application Developer . . . . . . . 156 WSAD preferences - Automatically build resource on save . . . . . . . . . . . . . . . . . . 160 WSAD SQLJ preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Adding sqlj files as text files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Create a new server. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Creating a new server and server configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 Create a JAAS entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 Creating a JDBC provider, step 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 Creating a JDBC provider, step 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 Creating a data source, step 1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Creating a data source, step 2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Create a Java Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 SQLJ customization script options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Create a new SQLJ file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 The directory for the SQLJ test project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Content of project ItsoSqlj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 SQLJ files and Java inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 Mapping strategies for CMP Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 Container-managed persistence and SQLJ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 Abstract persistence schema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Verifying FixPak WAS 5.1.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Two-phase commit processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

DB2 for z/OS and WebSphere: The Perfect Couple

8-2 8-3 8-4 8-5 8-6 8-7 8-8 8-9 9-1 10-1 10-2 10-3 10-4 10-5 10-6 10-7 10-8 10-9 11-1 11-2 11-3 11-4 11-5 11-6 11-7 11-8 11-9 11-10 11-11 11-12 11-13 11-14 11-15 11-16 11-17 11-18 11-19 11-20 11-21 11-22 11-23 11-24 11-25 11-26 11-27 11-28 11-29 11-30 11-31 11-32 11-33 11-34 11-35

Deployment Descriptor: Bean options for transaction management . . . . . . . . . . . . Method declaration of transaction type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Container transaction types for method execution. . . . . . . . . . . . . . . . . . . . . . . . . . Universal JDBC Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DB2 Universal JDBC Driver DataSource Custom Properties . . . . . . . . . . . . . . . . . DB2 UDB for z/OS as the transactions manager. . . . . . . . . . . . . . . . . . . . . . . . . . . Native DDF XA support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Single Global Transaction crossing multiple Application Servers . . . . . . . . . . . . . . Resource reference isolation settings for session Beans . . . . . . . . . . . . . . . . . . . . State of a connection object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connection pool parameter specification. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Statement cache size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using type 2 connectivity for local DB2 access . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connecting a WAS to a DB2 for z/OS via the type 4 XA Universal Driver. . . . . . . . Connecting a WAS to a DB2 for z/OS via a DB2 router system and a type 2 driver WebSphere Application Server configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . JVM Custom Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Custom Properties trace options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MVC design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MVC design with session Bean as entry to model. . . . . . . . . . . . . . . . . . . . . . . . . . Application sample tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New Connection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connection definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Confirm Filters selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Filter setting to NULLID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New look of the DB Servers pane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New button. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Project selections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJB level specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Project name and Enterprise Application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Import to folder in EJB project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Select of the import folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EJB project after import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NULLID.DEPT table overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NULLID.DEPT table columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NULLID.DEPT table Primary Key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NULLID.DEPT table foreign keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Columns of EMP_PHOTO_RESUME table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RDB to EJB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Back-end folder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mapping bottom-up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CMP type2.0 and name prefix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Map.mapxmi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Files generated by EJB to RDB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Generated code for DEPT table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Outline view of table EMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A department can have 0..m employees (0..1->0..m) . . . . . . . . . . . . . . . . . . . . . . . Beans - Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defined relationship between Emp-Dept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deployment descriptor - Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dept CMP entity Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deployment and RMIC code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Added finders for CMR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Figures

195 196 197 200 201 203 205 206 218 224 227 228 231 231 232 233 237 241 246 247 248 250 250 251 252 253 253 254 254 254 255 255 256 257 257 258 258 259 260 260 260 261 261 262 262 264 267 267 268 269 270 271 271 xi

11-36 11-37 11-38 11-39 11-40 11-41 11-42 11-43 11-44 11-45 11-46 11-47 11-48 11-49 11-50 11-51 11-52 11-53 11-54 11-55 11-56 11-57 11-58 11-59 11-60 11-61 11-62 11-63 11-64 11-65 11-66 11-67 11-68 11-69 11-70 11-71 11-72 11-73 11-74 11-75 11-76 11-77 11-78 11-79 11-80 11-81 11-82 11-83 11-84 11-85 11-86 11-87 11-88 xii

Java packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing the SQLJ option. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sqlj and Java code after translation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . skeleton of the Customization script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Additions for SQLJ under SQLJAntScripts directory . . . . . . . . . . . . . . . . . . . . . . . . SQLJ Customization script after . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Target pane from Ant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Properties pane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Beans panel for Emp_photo_resume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enterprise Bean creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New Bean in project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Give a name to the Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Selecting local or remote interfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Java files created . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The six original BMP classes/interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Beans panel of the EJB Deployment Descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . ITSODB2 to jdbc/ITSO1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New Enterprise Bean window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create an Enterprise Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enterprise Bean details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Session Bean layout view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Data transfer between controller and model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deployment Descriptor Bean section for ITSOAccess . . . . . . . . . . . . . . . . . . . . . . References in deployment descriptor to entity Beans . . . . . . . . . . . . . . . . . . . . . . . Select Beans to generate deployment code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Views for MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Select Web/Dynamic Web Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Project Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J2EE level and application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Including Struts support and some JSP tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Struts level 1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Struts operation principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Webcontent directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mapping in Struts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Actionservlet in the Web project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Modules in application ItsoEAR1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Installing a new application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accept the default . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . installation options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overview of the projects part of the J2EE application . . . . . . . . . . . . . . . . . . . . . . . JNDI names for the EJBs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifying the real datasource name. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . jdbc Data Source references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References to EJBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BMP reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Virtual host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Application server selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Check protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Install confirmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

272 273 274 275 275 276 276 277 278 279 280 281 281 281 282 283 289 289 290 291 291 292 292 293 294 295 296 297 299 299 300 300 301 301 302 303 303 304 306 307 308 308 309 309 310 310 311 311 312 312 312 313 313

DB2 for z/OS and WebSphere: The Perfect Couple

11-89 EmpIndex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 11-90 Employee and picture retrieved . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

Figures

xiii

xiv

DB2 for z/OS and WebSphere: The Perfect Couple

Tables
1-1 1-2 1-3 1-4 1-5 2-1 3-1 4-1 5-1 6-1 7-1 7-2 8-1 9-1 9-2 9-3 9-4 9-5 10-1 11-1 Columns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Columns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 JDBC differences between the DB2 Universal Driver and the DB2 Legacy Driver . . 31 SQLJ differences between the DB2 Universal Driver and the DB2 Legacy Driver . . 32 JDBC APIs specific to the DB2 Universal Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Some of the J2EE APIs supported by WAS 5.0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Supported Driver Providers with WAS v5.02 on z/OS . . . . . . . . . . . . . . . . . . . . . . . . 51 Data access comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Comparison of JDBC and SQLJ characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Client accounting strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 Subset of columns in the employee table from the DB2 sample database . . . . . . . 144 SQLJ isolation levels and their corresponding DB2 counterparts . . . . . . . . . . . . . . 145 Summary of JDBC Driver Provider support for WebSphere z/OS . . . . . . . . . . . . . . 201 Compatibility of page and row lock modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 Lock mode compatibility for table space and partition locks . . . . . . . . . . . . . . . . . . 211 Lock mode override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 DB2 UDB for z/OS and JDBC/SQLJ isolation mapping. . . . . . . . . . . . . . . . . . . . . . 214 Access Intent SQL append summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 Trace level options for the DB2 Universal Driver for SQLJ and JDBC . . . . . . . . . . 236 Connection properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

Copyright IBM Corp. 2005. All rights reserved.

xv

xvi

DB2 for z/OS and WebSphere: The Perfect Couple

Examples
1-1 1-2 1-3 1-4 1-5 1-6 1-7 1-8 1-9 1-10 3-1 3-2 3-3 3-4 5-1 5-2 5-3 6-1 6-2 7-1 7-2 7-3 7-4 7-5 7-6 7-7 7-8 7-9 7-10 7-11 7-12 7-13 7-14 7-15 7-16 7-17 7-18 7-19 7-20 7-21 7-22 7-23 7-24 9-1 10-1 10-2 10-3 10-4 CICS command-level services used with the CICS attachment facility . . . . . . . . . . . . 6 SQL statement that returns all columns from table EMP . . . . . . . . . . . . . . . . . . . . . . 13 Employees with a salary above $50,000 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Sample export statements for the PATH environment variable . . . . . . . . . . . . . . . . . 26 Sample export statements for the LIBPATH environment variable . . . . . . . . . . . . . . 27 Sample export statements for the CLASSPATH environment variable . . . . . . . . . . . 27 Running the DB2Binder utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Running the DB2T4XAIndoubtUtil utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 DDL to create the SYSIBM.INDOUBT table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Casting an instance of the JDBC class to an instance of the DB2-only class . . . . . . 32 Properties file for SSID DBD8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Start procedure for Servant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 included member with updated STEPLIB for DB2 V8 . . . . . . . . . . . . . . . . . . . . . . . . 70 Include member WSD7SZ with STEPLIB for DB2 V7 . . . . . . . . . . . . . . . . . . . . . . . . 77 Importing classes in a JDBC application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 UPDATE statement using parameter markers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 Compiling a Java application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Setting the workstation client strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 WSConnection using setClientInformation method . . . . . . . . . . . . . . . . . . . . . . . . . 137 Look up of the datasource using default values. . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 Look up of the datasource in detail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Caching the lookup information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 Getting a connection in SQLJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 Creating the context using Universal Driver features. . . . . . . . . . . . . . . . . . . . . . . . 143 Writing a SELECT statement using SQLJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 Disable automatic creation of DB2 packages during customization . . . . . . . . . . . . 148 Simple user transaction example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 setRollbackOnly() on the sessioncontext. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 Handling of a SQLException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 Handling SQLWarning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 Simple SQLJ source file. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 The sqlj.project.properties file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 The Ant script used to bind the packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 DBAEmployee.java file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 DBAEmployeeServlet.sqlj file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 DBAEmployeeEJB.sqlj file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Create a data transfer object based on information in the request . . . . . . . . . . . . . 180 Create an employee without using a transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Create an employee using a user transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 Calling SQLJ from a session Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 Calling SQLJ from an entity Bean with Bean-managed persistence . . . . . . . . . . . . 182 EJB QL example from our sample application. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 NullPointerException thrown by WAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 Example of a datasource lookup with a resource reference . . . . . . . . . . . . . . . . . . 217 Global driver properties file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 Universal Driver trace output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 Data source level trace output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 WSSystemMonitor example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244

Copyright IBM Corp. 2005. All rights reserved.

xvii

11-1 11-2 11-3 11-4 11-5 11-6 11-7 11-8 11-9 11-10 11-11 11-12 11-13 11-14 11-15 11-16

getImage() method. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . empl.Department . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Business method for getting Department information . . . . . . . . . . . . . . . . . . . . . . . CMP definitions for EMP table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CMR definitions for EMP table->DEPT table relationship . . . . . . . . . . . . . . . . . . . . EJBQL statement in the deployment descriptor. . . . . . . . . . . . . . . . . . . . . . . . . . . . Finder in ITSOEmpLocalHome.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Binding of the SQLJ packages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PhotoEmployeeBMPKey class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Local home interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Local interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BMP Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . getEmployee() method. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . getEmployee method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ITSOEmployee.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Action class for employee.do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

264 265 265 266 266 268 269 278 282 284 284 284 293 295 297 305

xviii

DB2 for z/OS and WebSphere: The Perfect Couple

Notices
This information was developed for products and services offered in the U.S.A. IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service. IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to: IBM Director of Licensing, IBM Corporation, North Castle Drive Armonk, NY 10504-1785 U.S.A. The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice. Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk. IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you. Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products. This information contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. COPYRIGHT LICENSE: This information contains sample application programs in source language, which illustrates programming techniques on various operating platforms. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the application programming interface for the operating platform for which the sample programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. You may copy, modify, and distribute these sample programs in any form without payment to IBM for the purposes of developing, using, marketing, or distributing application programs conforming to IBM's application programming interfaces.

Copyright IBM Corp. 2005. All rights reserved.

xix

Trademarks
The following terms are trademarks of the International Business Machines Corporation in the United States, other countries, or both:
AIX AS/400 Cloudscape CICS Distributed Relational Database Architecture DB2 Connect DB2 Universal Database DB2 DRDA Enterprise Storage Server Everyplace IBM ibm.com IMS iSeries MVS OS/2 OS/390 OS/400 PR/SM Rational Redbooks Redbooks (logo) RACF S/390 VTAM WebSphere z/Architecture z/OS zSeries

The following terms are trademarks of other companies: Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Other company, product, and service names may be trademarks or service marks of others.

xx

DB2 for z/OS and WebSphere: The Perfect Couple

Preface
DB2 for z/OS is a high-performance DBMS, with a very strong reputation in high-volume transaction workloads based on relational technology. WebSphere Application Server is a transaction monitor based on object-oriented technology, very much in sync with the J2EE standard. Can we marry the object world and relational world to create a high-volume, high-performance end-to-end OLTP environment? The answers can be found in this IBM Redbook. This book gives a broad understanding of the installation, configuration, and use of the IBM DB2 Universal Driver for SQLJ and JDBC in a DB2 for z/OS and OS/390 Version 7, and DB2 for z/OS Version 8 environment, with IBM WebSphere Application Server for z/OS for z/OS Version 5.02. It describes both type 2 and type 4 connectivity (including the XA transaction support) from a WebSphere Application Server on z/OS to a DB2 for z/OS and OS/390 database server. This publication also demonstrates the advantages of SQLJ in a DB2 environment, the SQLJ support in the IBM application development tool WebSphere Studio Application Developer, as well as the SQLJ support for Enterprise JavaBeans using container managed persistence.

The team that wrote this redbook


This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization, San Jose Center. Bart Steegmans is a Senior DB2 Product Support Specialist from IBM Belgium on assignment as a Data Management for z/OS Specialist at the ITSO, San Jose Center. He has over 15 years of experience in DB2. Before joining IBM in 1997, Bart worked as a DB2 system administrator at a banking and insurance group. His areas of expertise include DB2 performance, database administration, and backup and recovery. Carsten Block is a Senior IT Specialist with IBM Global Services in Denmark. He has been working in the computer industry for the last 15 years, and has worked at IBM for the last eight years. His area of expertise is mainly the J2EE platform, with a strong focus on back-end integration. He holds a Masters degree in Computer Science from the University of Copenhagen, Denmark. John De Dominicis is a Advisory IT DB2 Specialist from IBM Global Services Canada. He has supported DB2 for OS/390 and z/OS since joining IBM in 1997. His areas of expertise include identifying and resolving complex problems relating to DB2 installation, configuration, operation, performance, and recovery. Sean Lee is a member of the DB2 UDB for z/OS Test and Performance team. He specializes in the design and performance of highly scalable and available DB2 e-business solutions. He has worked as part of the DB2 Level 2 support team and as lead DB2 architect at the IBM Design Center for e-business transaction processing in Poughkeepsie. Sean has a degree in computer science from the State University of New York at Binghamton and has seven years of Information technology experience. Chao-Lin Liu joined IBM in 1984 and is currently a Certified Consulting IT Specialist focussing on data management e-business technologies. She is completing a special two-year assignment at the IBM Design Center for On Demand Business in Poughkeepsie,
Copyright IBM Corp. 2005. All rights reserved.

xxi

New York, and will soon join the DB2 development organization at the Silicon Valley Lab, San Jose as a DB2 for z/OS Performance Analyst. Chao-Lin holds a Masters of Science degree in Computer Science from Johns Hopkins University. Egide Van Aerschot works for the IBM Program Support Center in Montpellier, France since 1998, and is a member of the New Technology Center team, supporting and providing education for J2EE projects, WebSphere Business Integration, and connections to legacy systems. Before this he worked for IBM Belgium as an Account Systems Engineer, responsible for many projects related to transactional processing with major Belgium customers. During this period he also participated in several residencies in the United States. He graduated from the University of Louvain as a civil engineer. Thanks to the following people for their contributions to this project: Emma Jacobs International Technical Support Organization, San Jose Center Rich Conway Bob Haimowitz Julie Czubik International Technical Support Organization, Poughkeepsie Center Maria Sueli Almeida Sigi Bigelis Bill Bireley Delmar Blevins Maryela Weihrauch IBM Silicon Valley Laboratory, San Jose Kim Johnson IBM WebSphere Development, Poughkeepsie Terasa Kan IBM WebSphere Architecture and Development, Rochester Connie Tsui IBM Toronto Laboratory, Canada

Become a published author


Join us for a two- to six-week residency program! Help write an IBM Redbook dealing with specific products or solutions, while getting hands-on experience with leading-edge technologies. You'll team with IBM technical professionals, Business Partners and/or customers. Your efforts will help increase product acceptance and customer satisfaction. As a bonus, you'll develop a network of contacts in IBM development labs, and increase your productivity and marketability. Find out more about the residency program, browse the residency index, and apply online at:
ibm.com/redbooks/residencies.html

xxii

DB2 for z/OS and WebSphere: The Perfect Couple

Comments welcome
Your comments are important to us! We want our Redbooks to be as helpful as possible. Send us your comments about this or other Redbooks in one of the following ways: Use the online Contact us review redbook form found at:
ibm.com/redbooks

Send your comments in an Internet note to:


redbook@us.ibm.com

Mail your comments to: IBM Corporation, International Technical Support Organization Dept. QXXE Building 80-E2 650 Harry Road San Jose, California 95120-6099

Preface

xxiii

xxiv

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 1.

Introduction to DB2 for z/OS and OS/390


This chapter provides a short introduction to IBM DB2 Universal Database for z/OS and OS/390. As this publication is related to DB2 and WebSphere, we focus primarily on areas within DB2 related to data access from Java. This chapter discusses the following: Relational database management systems The DB2 Universal Database Family Components of DB2 UDB for z/OS and OS/390 DB2 data structures Structured query language (SQL) DB2 concepts Accessing DB2 from a Java environment IBM DB2 Universal Driver for SQLJ and JDBC Using the DB2 Universal Driver for SQLJ and JDBC

Copyright IBM Corp. 2005. All rights reserved.

1.1 Relational database management systems


Before relational database management system (DBMS) technology was available, application programmers had to know where data physically resided and how to access the data. This is acceptable if there are no changes to be made once the application is complete. However, change is inevitable. Each time a business need requires information the application does not currently provide, the application programmer has to add or rewrite the logic required to retrieve the necessary information. In addition, a data recovery process, if any, or reassurance of data integrity at any given time has to be completely controlled by the application programmer. The state of the data heavily relies on application programmers knowledge of the data, their application, and transaction flow. Over time, transaction volume steadily grows, rendering the dependency on application programmers suspect. In 1970, an IBM programmer working in IBM's Research Lab by the name of E.F. Codd questioned the process and proposed a concept that protected users of large databases from having to know how data is internally organized. This concept suggested that data be organized according to principles based on identified relations between various kinds of data. Welcome to the world of relational database management systems. A relational DBMS takes on the burden of physically organizing and retrieving data, allowing users and application programmers to focus on identifying the data they require. It does not end there. A (relational) DBMS is also comprised of other components, which are either transparent to the user or require very little intervention. For example: Multiple user connectivity - Allows and manages more than one user connection to the database and access to data at any given time. Data integrity - Internal locking ensures the risk of data corruption is eliminated. Recoverability - The ability to recover data to a previous point in time or to a current state when needed. Security - Controls access to data and resources by allowing only authorized users access to certain data under specific circumstances.

1.2 The DB2 Universal Database Family


The DB2 Universal Database (UDB) Family has much more to offer than simply organizing your data. The DB2 UDB product is a scalable, robust, multifaceted data processing engine, so versatile that it can be tailored and effectively utilized for many different business solutions, large or small. In this publication, we focus on accessing data stored in DB2 for z/OS and OS/390 from a Java-based environment via IBM WebSphere for z/OS. However, this section introduces the other members that make up the DB2 UDB family.

1.2.1 DB2 UDB for Linux, UNIX, and Windows


Although there are many editions of DB2 UDB for Linux, UNIX, and Windows available, they all share the core capabilities including, but not limited to: Automation functionality such as self-configuring, self-optimizing, and self-managing capabilities Federated capabilities making it possible to integrate information as Web Services XML enhancements allowing programmers to easily integrate DB2 and XML information

DB2 for z/OS and WebSphere: The Perfect Couple

Performance and scalability enhancements such as new streamlined application drivers (ODBC, OLE DB, JDBC, and SQLJ) and new client architecture Business intelligence capabilities to easily organize data allowing for faster and more insightful queries Currently, the available editions of DB2 UDB for Linux, UNIX, and Windows Version 8.2 and the operating systems on which they operate include: DB2 UDB Enterprise Server Edition available for AIX, HP-UX, Linux, Solaris, Windows NT, Windows 2000, and Windows 2003 operating systems. DB2 UDB Workgroup Server Unlimited Edition available for AIX, HP-UX, Linux, Solaris, Windows NT, Windows 2000, Windows 2003, and Windows XP operating systems having up to four CPUs. DB2 UDB Workgroup Server Edition available for AIX, HP-UX, Linux, Solaris, Windows NT, Windows 2000, Windows 2003, and Windows XP operating systems having up to four CPUs. DB2 UDB Personal Edition available for Linux, Windows NT, Windows 2000, Windows 2003, and Windows XP (with V8 Fixpack 4 or later) operating systems. DB2 UDB Express Edition available for Linux, Windows NT, Windows 2000, Windows 2003, and Windows XP operating systems having up to two CPUs. It comes in two flavors: DB2 UDB Express Edition (named user option), where registered users are entitled to the database DB2 UDB Express Edition CPU Option, where each available CPU must be entitled DB2 UDB Universal Developers Edition available for AIX, HP-UX, Linux, solaris, Windows NT, Windows 2000, Windows 2003, and Windows XP operating systems. Attention: Each developer must have an individual license. The software in this package cannot be used for production systems. DB2 UDB Personal Developers Edition available for Linux, Windows NT, Windows 2000, Windows 2003, and Windows XP operating systems. For more detailed information see: http://www.ibm.com/software/data/db2/udb/ On the Linux, UNIX, and Windows platforms, we also have the suite of DB2 Connect products that provide the application enablement and robust, highly scalable communication infrastructure for connecting Web, Windows, UNIX, Linux, OS/2, and mobile applications to S/390 and AS/400 data. DB2 Connect comes in several flavors: DB Connect Enterprise Edition DB2 Connect Personal Edition DB2 Connect Unlimited Edition DB2 Connect Application Server Edition For more information on DB2 Connect, see:
http://www.ibm.com/software/data/db2/db2connect/

Chapter 1. Introduction to DB2 for z/OS and OS/390

1.2.2 DB2 UDB for iSeries


DB2 Universal Database is also available on the iSeries (OS/400) platform. In this integrated environment, DB2 UDB for iSeries offers many unique features such as: Built-in SQL query engine and new statistics engine, resulting in 25 times performance improvements in large, complex queries Improved data warehousing performance with IBM's patented encoded vector indexing supplementing the traditional binary radix tree indexing

1.2.3 DB2 Server for VSE and VM


Although it is not an official member of the DB2 Universal Database Family, DB2 Server for VSE and VM operates in a unique environment offering many of the same features, such as: Powerful data integrity capabilities Full archive and recovery services

1.2.4 More information on the DB2 UDB family, related tools, and products
Of course, the latest information on the complete DB2 UDB family is available on the Internet at the following URL:
http://www.ibm.com/software/data/db2/

1.3 Components of DB2 UDB for z/OS and OS/390


In this section we discuss the fundamental concepts, components, and terminology of DB2 UDB for z/OS and OS/390. Except where noted, more information on all of the following sub-topics is available in the DB2 Universal Database for z/OS Version 8 Administration Guide, SC18-7413, and the DB2 Universal Database for z/OS Version 8 SQL Reference, SC18-7426.

1.3.1 DB2 UDB for z/OS and OS/390 address spaces


DB2 is a formal subsystem of the z/OS and OS/390 operating system. Understanding the structure of DB2 can help conceptualize end-to-end data flow. An address space is a complete range of storage addresses bound by a beginning and an ending address that can be accessed by the operating system. Although there are different types of address spaces, each address space can be considered its own entity, which operates independently. In other words, an address space can be thought of as a logical box of memory. DB2 for z/OS and OS/390 uses a number of address spaces.

System services address space


The actual address space name is ssnmMSTR, where ssnm is the DB2 subsystem name. This address space has many responsibilities, some of which include: General command processor Storage manager Initialization procedures System parameter manager Log manager Recovery manager

DB2 for z/OS and WebSphere: The Perfect Couple

As a user, you may be familiar with ssnmMSTR as the place to look for system messages related exclusively to DB2.

Database services address space


This address space is named ssnmDBM1, where ssnm is the DB2 subsystem name. This address space manages most DB2 operations that are transparent to the user, such as: Buffer manager Data manager Relational data system Stored procedures manager LOB manager Attention: In the 64-bit DB2 for z/OS Version 8 environment, buffer pools and other storage areas reside above the 2 GB bar in the DBM1 address space allowing them to scale to extremely large sizes (provided enough real storage exists on the system).

Distributed data facility services address space


This address space name is ssnmDIST, where ssnm is the DB2 subsystem name, but it is commonly referred to as Distributed Data Facility (DDF). The DDF address space is the initial contact point of all distributed threads connecting to a DB2 for z/OS and OS/390 subsystem. Distributed threads gain access to the data once communication has been established with the DDF address space. This is also the case when connecting to DB2 for z/OS and OS/390 using the Type 4 IBM DB2 Universal Driver for SQLJ and JDBC.

Internal resource lock manager address space


The internal resource lock manager (IRLM) is unique as it is both a separate subsystem and an integral component of DB2. IRLM handles all locking related to a specific DB2 subsystem. Without an IRLM address space, DB2 for z/OS and OS/390 will not function. In fact, if a DB2 subsystem is up and running and the IRLM address space, for whatever reason, is no longer available, the DB2 subsystem will cease processing requests and immediately terminate. Data integrity is compromised when IRLM is not available. This is why the DB2 subsystem is designed to come down when IRLM is not around to handle locking.

WLM-established stored procedure address space


WLM-established address spaces are handled in order of priority. They are execution environments isolated from other stored procedures or user-defined functions running in other address spaces. There can be zero to many WLM address spaces for stored procedures and user-defined functions. As suggested by the name, these address spaces are managed by Workload Manager, an z/OS operating system component. WLM-established stored procedures are defined with the WLM ENVIRONMENT appl-env-name keyword on the CREATE PROCEDURE statement. Attention: The Resource Recovery Services (RRS) attachment is required for stored procedures that run in a WLM-established address space.

DB2-established stored procedure address space


This address space, ssnmSPAS, where ssnm is the DB2 subsystem name, provides an isolated execution environment for DB2-established stored procedures. However, there is only one SPAS address space available for all DB2-established stored procedures to run in. This can be undesirable. DB2-established stored procedures are defined with the NO WLM ENVIRONMENT keyword on the CREATE PROCEDURE statement.

Chapter 1. Introduction to DB2 for z/OS and OS/390

Important: In DB2 UDB for z/OS Version 8, the NO WLM ENVIRONMENT keyword has been deprecated. Existing DB2-managed stored procedures continue to work in V8, but all newly created stored procedures in a DB2 UDB for z/OS Version 8 subsystem require a WLM environment defined on the CREATE PROCEDURE statement.

1.3.2 DB2 attachment facilities


An attachment facility can be thought of as a required portal or gateway when a user request to connect to a DB2 subsystem originates from certain environments. In order to communicate with DB2 for z/OS from a Customer Information Control System (CICS), Information Management System (IMS), Time Sharing Option (TSO), batch or WebSphere (when using RRS) environment, a DB2 attachment facility is required to establish a session. Attachment facilities are subcomponents of DB2 that run in the users address space.

CICS
The CICS attachment facility, language interface module DSNCLI, is provided by the CICS product. It receives CICS application requests and passes them to DB2. Example 1-1 shows the standard CICS command-level services that can be used.
Example 1-1 CICS command-level services used with the CICS attachment facility EXEC CICS WAIT EXEC CICS ABEND

By issuing DB2 commands, an authorized CICS terminal operator is able to control and monitor DB2 and the attachment facility.

IMS
The IMS attachment facility, program interface DFSLI000, is required to access DB2 from an IMS environment. It receives and interprets requests for access to DB2 databases using exits provided by IMS subsystems. The IMS attachment facility also allows an authorized IMS terminal operator the ability to issue DB2 commands such as starting and stopping DB2 databases.

TSO
The TSO attachment facility offers unique functionality. It is required for binding application plans and packages and to execute online DB2 functions. In fact, the CICS and IMS attachment facilities depend on the TSO attachment facility for these functions. Access to DB2 in foreground through a TSO terminal or in batch mode through the TSO terminal monitor program (TMP) can be accomplished with the TSO attachment facility. In addition, two command processors are provided: DSN command processor - Primarily used for batch jobs, uses the TSO attachment facility and runs as a TSO command processor DB2 Interactive (DB2I) - An interactive connection to DB2 allowing users to run SQL statements, issue DB2 commands, and run DB2 utilities using Interactive System Productivity Facility (ISPF) panels With the TSO attachment facility, load module DSNELI, access to DB2 is fairly simple. On the other hand, this also means that an application has less control over the state of the connections and, when using DSN services, applications running under the control of DSN.

DB2 for z/OS and WebSphere: The Perfect Couple

Call attachment facility (CAF)


As the alternative attachment facility for TSO and batch applications, CAF supplies additional connection functionality and greater control over the execution environment including: Explicit control over the state of the connection to DB2. Used with or without TSO TMP. DB2 version verification. Translation of DB2 reason codes, return codes, and abend codes into customized messages. Establish an implicit connection to DB2 (with a default subsystem identifier and a default plan name) by using SQL statements or instrumentation facility interface (IFI) calls without first calling CAF (available in all currently supported DB2 versions). CAF uses language interface module DSNALI.

Resource Recovery Services (RRS)


RRS is a component of the z/OS operating system that provides system-wide coordination of commit processing (including two-phase commit) over the life of a transaction. With the additional functionality included in z/OS RRS, the RRS attachment facility (RRSAF) has become the successor to CAF. With RRSAF, it is possible to: Coordinate DB2 updates with updates made by all other resource managers that also use z/OS RRS in an z/OS system. Establish an implicit connection to DB2 (with a default subsystem identifier and a default plan name) by using SQL statements or instrumentation facility interface (IFI) calls without first calling RRSAF (in DB2 Version 8). To use RRSAF, load module DSNRLI provided by DB2 must be available, and the z/OS RRS component must be started. Additional information on the attachment facilities is documented in the DB2 Universal Database for z/OS Version 8 Application Programming and SQL Guide, SC18-7415. Figure 1-1 on page 8 illustrates the logical flow of data when a request is made from a z/OS or distributed environment. Depending on the originating environment, a z/OS request uses the associated attachment facility to establish communication with the DB2 for z/OS subsystem. For example, a CICS request would use the CICS attachment facility to establish a connection. Once the connection is established, the general flow of data begins in the MSTR address space. This is where the request is initially validated and the necessary output messages, if any, are generated. Once the MSTR address space declares the request to be valid, data flow continues to the DBM1 address space. The DBM1 address space does much of the legwork. However, the IRLM address space must provide the necessary locking before and data is ultimately passed back to the requester to insure data integrity. Once the locks have been acquired, the data is retrieved and passed back to the requester.

Chapter 1. Introduction to DB2 for z/OS and OS/390

DB2 OS/390 or z/OS subsystem

TSO
attachment facility

MSTR
address space

DDF
address space

IMS
attachment facility

CICS
attachment facility

z/OS environment

CAF RRSAF

Distributed environment

DBM1
address space

IRLM
address space

Figure 1-1 Basic data flow in a DB2 subsystem from z/OS and distributed environments

A request from a distributed environment is very similar to the data flow originating from within a z/OS environment (local attachment). The significant difference is using the DDF address space to establish a connection as opposed to an attachment facility. This is also the case when using JDBC Type 4 connectivity provided by the IBM DB2 Universal JDBC Driver to connect to a DB2 for z/OS subsystem. In this scenario, the Universal Driver is acting as a DRDA application requester to establish a connection into the DDF address space (acting as a DRDA application server) of the DB2 for z/OS subsystem. This is discussed in more detail in Accessing DB2 from a Java environment on page 19.

1.4 DB2 data structures


DB2 data structures can be conceptualized as a hierarchy of objects that have at least one relationship to another object. Figure 1-2 on page 9 illustrates a basic relationship between the DB2 data structures.

DB2 for z/OS and WebSphere: The Perfect Couple

Database
Table space

Storage group

Table

Volume 1

Index space

Volume 2

Index Volume 3

Figure 1-2 DB2 data structure hierarchy and relationships

1.4.1 Databases
In DB2 for z/OS, a database is a logical grouping of data objects. A database is defined by using the CREATE DATABASE statement. The default database is named DSNDB04. A single database, for example, can contain all the data that is associated with one application or with a group of related applications. Collecting that data into one database allows you to start or stop access to all the data in one operation. You can also grant authorization for access to all the data as a single unit. Assuming that you are authorized to do so, you can also access data that is stored in different databases. Databases in a DB2 UDB for z/OS environment are fundamentally different compared to databases in DB2 UDB for Linux, UNIX, and Windows environments. For example, in a DB2 UDB for z/OS environment: Recovery logs are not database specific. All the databases in the entire DB2 subsystem use the same recovery logs. DB2 configuration parameters (DSNZPARMs) are for the entire DB2 subsystem. Databases such as the DB2 catalog database (DSNDB06), default database (DSNDB04), and the work file database (DSNDB07) are not isolated and are able to interact with each other. These are shared within the DB2 subsystem. In a DB2 UDB for Linux, UNIX, and Windows environment: Each database contains its own logs and configuration files.

Chapter 1. Introduction to DB2 for z/OS and OS/390

Databases are isolated from each other. This means that, without any middleware intervention (or using DB2 federated database technology), a query involving tables from two different databases is not possible. The DB2 catalog and temporary space are created as table spaces, and are specific to a certain database.

1.4.2 Storage groups


A storage group defines a name for a volume or group of volumes that determine where the table space and index space data sets will reside. Use the CREATE STOGROUP statement to define a storage group. All volumes of a given storage group must have the same device type. The table spaces and index spaces of a single database can be stored in different storage groups.

1.4.3 Data sets


DB2 uses Virtual Storage Access Method (VSAM) linear data sets (LDSs) to physically store data. Table spaces and index spaces, also known as DB2 page sets, are the only DB2 objects that are physically backed by data sets. Tip: In DB2 UDB for z/OS Version 8, data sets can be defined with variable VSAM control interval sizes. This can potentially improve query processing performance. Prior to DB2 UDB for z/OS Version 8, DB2 uses 4 KB control intervals for all data sets.

1.4.4 Table spaces


Table spaces are DB2 storage structures backed by one or more data sets that store one or
more tables. Whenever a table space is created, it is explicitly or implicitly assigned to an existing database. As illustrated in Figure 1-3 on page 11, there are four types of table spaces that can be defined using the CREATE TABLESPACE statement.

Segmented
This divides the available space into groups of pages called segments. Each segment is the same size. The size of the segment is determined by the SEGSIZE keyword when the table space is created. The integer specified for SEGSIZE must be a multiple of 4 and must be between 4 and 64, inclusive. A segment contains rows from only one table. You can have one or more tables in a segmented table space.

Partitioned
This divides the available space into separate units of storage called partitions. Each partition is backed by a physical data set and stores data of only one table. The number of partitions is determined when the table space is created with the NUMPARTS keyword. In DB2 for z/OS Version 8, an integer from 1 to 4096 can be used when specifying a value for NUMPARTS. Partitions of a given table space can be independently assigned to different storage groups.

Large object (LOB)


This holds large object data such as graphics, video, or very large text strings and is defined with the CREATE LOB TABLESPACE statement. Only a table defined as an auxiliary table can be defined in a LOB table space. This auxiliary table is where the actual LOB data resides.

10

DB2 for z/OS and WebSphere: The Perfect Couple

Simple
This is the type of table space created if neither LOB, NUMPARTS or SEGSIZE is specified when defining a table space. Unlike segmented table spaces, the rows of different tables are not kept separate in a simple table space. It is for this reason, although simple table spaces can contain more than one table, it is recommended (in general) that only one table exists at any given time in a simple table space.

Database
Partitioned table space

Storage group A

Table

Table

Table Volume 1

Simple table space Storage group B

Table
Segmented table space

Volume 2 Table

Volume 3

Volume 4

Table

Table

Storage group C LOB table space

Auxiliary Table

Volume 5

Volume 6

Figure 1-3 Different types of table spaces available in DB2 UDB for OS/390 and z/OS

1.4.5 Tables
Tables are logical structures, and are made up of an ordered set of columns. A table is defined using the CREATE TABLE statement. Every table must have one or more columns, but the number of rows can be zero or more. Although the data is physically stored in a data set at the table space level, the table structure is referred to when accessing the data.
Only auxiliary tables can store LOB data in LOB table spaces. Auxiliary tables are defined using the CREATE AUXILIARY TABLE statement. A LOB auxiliary table is always associated with a non-LOB table that is defined in a non-LOB table space. This non-LOB table is called a base table. The base table contains one or more (logical) LOB columns. The values in the LOB column are a pointers to the actual LOB data in the auxiliary table. In order to retrieve the LOB data, a query against the base table is performed. A LOB table space must be in the same database as the table space that contains the base table.

1.4.6 Indexes
An index is an ordered set of pointers to rows of a table. As an index in a book points to a page that a specific topic is discussed, you can think of a DB2 index in the same way. Each
Chapter 1. Introduction to DB2 for z/OS and OS/390

11

index entry points to a specific row of a table. Each index is based on the values of data in one or more columns of a table. Each index occupies its own index space (a physical data set on disk). An index is defined using the CREATE INDEX statement. Once the index is defined, DB2 maintains the index. For example, whenever a row is inserted into the table, a corresponding index entry is automatically created in the index by DB2. However, maintenance such as reorganizing or recovering an index is not automatically performed by DB2. The DB2 Universal Database for z/OS Version 8 Utility Guide and Reference, SC18-7427, contains additional information on the DB2 REORG and RECOVER utilities. The most common use for an index is to improve performance and ensure uniqueness. In most cases, access to data is faster with an index than with a table space scan of the entire data. There are different types of indexes that can be defined.

Unique indexes
Unique indexes ensure that no duplicate values of the index key exist in the table. Unique indexes are also an important part of implementing referential constraints among the tables in your DB2 database. You cannot define a foreign key unless the corresponding primary key already exists and has a unique index defined against it.

Clustering indexes
Clustering indexes direct DB2 to insert rows into the table in the order of the clustering key values. The first index that you define on the table serves implicitly as the clustering index unless you explicitly specify the CLUSTER keyword when you create or alter another index. In DB2 UDB for z/OS Version 8, CLUSTER can be specified for any index, whether or not it is a partitioning index.

Partitioning indexes
To indicate which rows go into which partition of a partitioned table space, you select one or more (partitioning) columns, and indicate for each partition the highest value that should go into that partition. The highest value for a partition is referred to as the limit key of the partition. Before DB2 for z/OS Version 8, the partitioning key columns and the limit key values in the PART VALUES clause are specified on the CREATE INDEX statement. This type of partitioning is referred to as index-controlled partitioning. Beginning with DB2 for z/OS Version 8, there is a new option to defining table-controlled partitioning by using partitioning clause (PARTITION BY) on the CREATE TABLE statement. An index is considered to be a partitioning index if the left-most columns in the index are the same as the partitioning columns, and have the same collating sequence as the partitioning columns (that you specify the limit keys for). Because prior to DB2 for z/OS Version 8 all partitioned table spaces are index-controlled partitioned table spaces, the index that you specify the partitioning columns and limit keys for, is by definition a partitioning index. Prior to Version 8 that index is always physically partitioned, as well as the explicit clustering index for the partitioned table. In Version 8, a partitioning index is not always physically partitioned, nor does it have to be the clustering index. For more information see DB2 for z/OS Version 8 Everything you ever wanted to know, ... and more, SG24-6079.

12

DB2 for z/OS and WebSphere: The Perfect Couple

Secondary indexes
Secondary indexes are indexes that are not partitioning indexes but are defined against a partitioned table space. Traditionally, secondary indexes are used to enforce a uniqueness constraint, or to provide a better access path to data for queries. In DB2 UDB for z/OS Version 8, there are two types of secondary indexes: Data-partitioned secondary index (DPSI) - A DPSI has the same number of partitions as the partitioned table space in which the referenced table resides. Index keys in a particular index partition reference only data of the same table space partition. DPSIs can also be a clustering index. DPSIs cannot be unique. Nonpartitioned secondary index (NPSI) - Basically, an index that performs the traditional roles of a secondary index and is not partitioned. NPSIs can be created against a table in a partitioned or nonpartitioned table space. A NPSI resides in a single index space (although it may consist of multiple physical data sets, for example, when using the PIECESIZE keyword on the CREATE INDEX statement).

1.5 Structured query language (SQL)


We now know how data is stored in the data structures, but how do we access the DB2 tables to manipulate the data in order to return meaningful information? This is the role of the Structured Query Language (SQL). SQL is used to retrieve and manipulate data stored in a relational database. One unique aspect of SQL that sets it apart from traditional programming languages is you specify what you want done, not how to do it. For example, accessing data involves only indicating which table(s) and column(s) contain the data you like to see in your result. You do not need to describe how to get to the data. This is why SQL is a declarative query language. Example 1-2 shows a basic SQL statement used to retrieve all the columns from a table containing employee information called EMP. The asterisk (*) character is used to signify all columns should be returned. The result is shown in Table 1-1.
Example 1-2 SQL statement that returns all columns from table EMP SELECT * FROM EMP; Table 1-1 Columns EMPNO 054124 001427 000003 000341 001541 LASTNAME HOWE DE DOMINICIS BAI RAITAKARI SHEPPARD HIREDATE 2000-10-12 1998-06-01 1998-06-08 1971-02-28 1995-03-15 DEPTNO D12 D12 E11 A10 C05 SALARY 85100 49900 82500 120500 42500

Having a business need to see all the information for each employee may not be practical. Let us say we want to know only the employees having a salary greater than $50,000. Example 1-3 depicts the SQL statement that can be used to return results showing only the last name of the employee and the salary of the employee for all employees who have a salary above $50,000. The result of the query is shown in Table 1-2 on page 14.
Example 1-3 Employees with a salary above $50,000 SELECT LASTNAME, SALARY FROM TABLE EMP

Chapter 1. Introduction to DB2 for z/OS and OS/390

13

WHERE SALARY > 50000; Table 1-2 Columns LASTNAME HOWE BAI RAITAKARI SALARY 85100 82500 120500

SQL statements are divided into three categories: Data Definition Language DDL refers to the SQL statements that create or modify data objects. The CREATE, ALTER, and DROP statements are examples of DDL. DCL identifies SQL statements that (mainly) affect security and user authorization when attempting to access DB2 data objects. GRANT, REVOKE, and LOCK TABLE statements are examples of DCL.

Data Control Language

Data Manipulation Language DML identifies SQL statements that access the actual data. DML includes SQL statements such as SELECT, UPDATE, INSERT, and DELETE. When an SQL statement is executed, a sequence of internal operations takes place to optimize data retrieval. This transformation occurs when the SQL statement is prepared. This transformation is also known as binding. All executable SQL statements must be prepared before they can be executed. The result of preparation is the executable or operational form of the statement. There are primarily two categories of SQL. There is static SQL and dynamic SQL. When the SQL statement is prepared, the persistence of its operational form are the primary factors that distinguish static SQL from dynamic SQL.

1.5.1 Static SQL


Static SQL is normally embedded within an application program written in a host language. This being the case, static SQL statements in a source program must be processed before the program is compiled since the compiler of the host language will not comprehend the SQL statements. This processing can be accomplished through the DB2 precompiler or the SQL statement coprocessor. The DB2 precompiler or the coprocessor checks the syntax of the SQL statements, turns them into host language comments, and generates host language statements. Static SQL statements are prepared before the program is executed and the operational form of the statement persists beyond the execution of the program. It is said to be bound into a plan or a package.

1.5.2 Dynamic SQL


Just like static SQL statements, dynamic SQL statements can also be embedded in application programs and must be precompiled with the DB2 precompiler or the SQL statement coprocessor. However, dynamic SQL statements are constructed and prepared at run time. Whether the operational form of the statement is persistent depends on whether dynamic statement caching is enabled.

14

DB2 for z/OS and WebSphere: The Perfect Couple

Dynamic SQL can also be used by so-called call-level interfaces, such as ODBC. In this case, the SQL statement is not embedded into the host language, so there is no need to precompile the program itself prior to execution. The SQL statement is passed to the DBMS as an input parameter to a callable function implemented by the call-level interface. For more information, see DB2 Universal Database for z/OS Version 8 ODBC Guide and Reference, SC18-7423, and Squeezing the Most Out of Dynamic SQL with DB2 for z/OS and OS/390, SG24-6418. Complete SQL statement syntax as well as examples are available in the DB2 Universal Database for z/OS Version 8 SQL Reference, SC18-7426. Additional information on the traditional program preparation process is discussed in DB2 packages, plans, collections, and package lists on page 17. Complete details regarding precompilation, preparation of static SQL statements, compilation of modified source programs, and dynamic statement caching are available in the DB2 Universal Database for z/OS Version 8 Application Programming and SQL Guide, SC18-7415.

1.5.3 Industry standards


SQL is a standardized language for defining and manipulating data in a relational database. The standards are maintained by the International Organization for Standardization (ISO) and the American National Standards Institute (ANSI). DB2 UDB for z/OS is consistent with the following industry standards for SQL: Information technology - Database languages - SQL- Part 1: Framework (SQL/Framework) ISO/IEC 9075-1:1999 Information technology - Database languages - SQL- Part 2: Foundation (SQL/Foundation) ISO/IEC 9075-2:1999 Information technology - Database languages - SQL- Part 4: Persistent Stored Modules (SQL/PSM) ISO/IEC 9075-4:1999 Information technology - Database languages - SQL- Part 5: Host Language Bindings (SQL/Bindings) ISO/IEC 9075-5:1999 Information technology - Database languages - SQL- Part 10: Object Language (SQL/OLB) ISO/IEC 9075-10:2000 Information technology - Database languages - SQL- Part 13: SQL Routines and Types Using the Java Programming Language (SQL/JRT) ISO/IEC 9075-13:2002 Information technology - Database languages - SQL- Part 14: XML-Related Specifications (SQL/XML) ISO/IEC 9075-14:2003 ANSI X3.135-1999, Database Language SQL Additional information on the industry standards is available at the ISO and ANSI Web sites: http://www.iso.org http://www.ansi.org

1.6 DB2 concepts


This section introduces a handful of key DB2 UDB for OS/390 and z/OS concepts to help provide a basic understanding of how a relation database functions. There are many more concepts involved, including additional information on the concepts mentioned in this section, which are discussed in the DB2 Universal Database for z/OS Version 8 Administration Guide, SC18-7413.

Chapter 1. Introduction to DB2 for z/OS and OS/390

15

1.6.1 Referential constraints


A key is one or more columns that is identified in the description of a table, an index, or a referential constraint. You can assign a primary key and foreign keys to tables. DB2 can automatically enforce the integrity of references from a foreign key to a primary key by guarding against insertions, updates, or deletions that violate the integrity. Primary key Foreign key A column or set of columns whose values uniquely identify each row Columns of other tables whose values must be equal to values of the primary key they point to

Figure 1-4 on page 17 illustrates the primary and foreign key relationships in sample tables DEPT and EMP. These are the same tables and referential constraints that are used in the examples throughout this publication. Tables DEPT and EMP have two referential constraints between them. In addition, table DEPT has a self-referencing constraint. The name given to a constraint is arbitrary. However, it is a good idea to try to give the constraint a meaningful name. Referential constraint RDEPT represents a relationship between the WORKDEPT column of table EMP and the primary key of table DEPT, column DEPTNO. This constraint is in place to ensure that each record in the EMP table has a valid department number, which is in the DEPT table. In addition, if a record is deleted from the DEPT table, this constraint is specifically defined to set the WORKDEPT column to NULL for all employees who had the department number that was deleted. This is accomplished by defining the referential constraint as ON DELETE SET NULL. Referential constraint REMP represents a relationship between the MGRNO column of table DEPT and the primary key of table EMP, which is column EMPNO. REMP is similar to RDEPT, the difference being the direction of the constraint (from table DEPT to table EMP) and the columns involved. This constraint is in place to ensure that each record in the DEPT table has a valid employee number in table EMP for the manager of the department. When a record is deleted from table EMP and that record happens to be an employee who managed a department, this constraint is defined to set the MGRNO column to NULL for all departments that had the employee number that was deleted. Much like the RDEPT constraint, this is accomplished by defining the referential constraint as ON DELETE SET NULL. Referential constraint RSELFD is a self-referencing constraint involving only table DEPT. By definition, a foreign key must point to the primary key of a table. This rule is being honored as RSELFD references column ADMRDEPT of table DEPT and points back to its own primary key, which is column DEPTNO. Unlike constraints RDEPT and REMP, RSELFD is defined as ON DELETE CASCADE. This referential constraint is in place to ensure that the department number in column ADMRDEPT is a valid department number. This is done by making sure the department number specified in column ADMRDEPT is also specified in column DEPTNO. When a record in DEPT is deleted, this constraint propagates the delete operation to the dependent rows.

16

DB2 for z/OS and WebSphere: The Perfect Couple

Table DEPT
Primary Key

Referential constraint RSELFD

DEPTNO C01 D11 E11

DEPTNAME SENIOR MGMT SALES TECHNICAL

MGRNO

ADMRDEPT

000006 C01 000003 E11 000003 C01


Referential constraint REMP

Table EMP
Primary Key Referential constraint RDEPT

EMPNO

LASTNAME WORKDEPT C01 C01 D11

JOB IT TECH MGR SALES

000003 BAI 000006 TIFFNEY 002003 RIZZA

Figure 1-4 Referential constraints between tables DEPT and EMP

1.6.2 DB2 packages, plans, collections, and package lists


An application that contains embedded SQL is precompiled to extract the SQL statements from the source code. This is done because the source code language compiler does not recognize SQL statements as legitimate syntax of the source code language used. Therefore, the source code must be run through the DB2 precompiler before being compiled by the source code compiler. Alternatively, if the source code compiler provides a SQL statement coprocessor, there is no need to run the source code through the DB2 precompiler. With the SQL statement coprocessor, the SQL statements are extracted and the source code is compiled in one step. These two methods of precompilation are illustrated in Figure 1-5 on page 18. The main goal of the DB2 precompiler and the SQL statement processor is to accomplish two things: Replace the SQL statements in your source programs with calls to DB2 language interface modules. Create a database request module (DBRM).

Packages and plans


A DBRM contains a modified rendition of all the SQL statements extracted from the source program. Generally, you should not be concerned with the contents of the DBRM as there is no further user interaction with the DBRM itself. The DBRM communicates the SQL requests to DB2 during the bind process. With the DBRM generated by the DB2 precompiler or the SQL statement processor, it can be either bound into a package or directly into an application plan. Program preparation including the bind process is illustrated in Figure 1-5 on page 18.
Chapter 1. Introduction to DB2 for z/OS and OS/390

17

Each package contains only one DBRM. When a package is bound, there are many bind options that can be specified. These options determine how the SQL statements in the DBRM will ultimately execute in DB2. Bind options are very powerful. Some of the application characteristics they can influence are: The user ID used for authorization checking How DB2 locks data and when the locks are released Whether DRDA orDB2 private protocol is used when connecting to a remote site If parallel processing is used when a query is run If the local dynamic statement caching should be used In general, a plan is similar to a package in terms of bind options; however, the differences are: Packages and/or DBRMs are bound in a plan. A plan relates an application process to a local instance of DB2. One or more DBRMs can be directly bound in a plan. One or more packages can be bound in a plan. A plan can be made up of both DBRMs and packages. In almost all cases, an application must have a plan bound before it can run. There is one exception to this rule. A (explicit) plan is not required when using a distributed connection into DB2. When accessing DB2 through DDF, the package (which is required) runs under a system plan called DISTSERV.

Source program

SQL Statement coprocessor and compile

Linkedit

Object program

Load module

DB2 Precompiler

DBRM

Modified source

Compile or assemble

BIND PACKAGE

BIND PLAN

Plan

Object program

Linkedit

Package

Load module

Figure 1-5 Program preparation using the DB2 precompiler or SQL statement coprocessor

Creating a package or a plan, a process unique to DB2, involves binding one or more DBRMs using the BIND PACKAGE or BIND PLAN commands. Complete syntax for the BIND PACKAGE and BIND PLAN commands as well as detailed information about the bind options 18
DB2 for z/OS and WebSphere: The Perfect Couple

are documented in the DB2 Universal Database for z/OS Version 8 Command Reference, SC18-7416. Note, however, that when using SQLJ with the IBM DB2 Universal Driver for SQLJ and JDBC, no DBRM is produced when the serialized profile is customized. For more information, see 5.4.2, SQLJ program preparation process on page 117.

Collections
There are many binding strategies that can be utilized to best suit the environment the application will run in, one of which is to use a collection. A collection is an arbitrary name given to a group of associated packages. To help visualize the concept of a collection, think of a collection as a department name, and the employees that work in the department as the packages. The collection name is a parameter that is specified as part of the BIND PACKAGE command.

Package lists
As indicated by its name, a package list is simply a list of packages that determines which packages are included in an application plan. The package list is specified with the PKLIST parameter of the BIND PLAN command. A collection can also be specified with the PKLIST parameter. The order in which packages or collections in the PKLIST are specified is important. The same order will be used for the search order at run time. This can affect performance. The use of packages, plans, and collections in a WebSphere environment is discussed in more detail in Chapter 5, DB2 application development in a WebSphere environment on page 109.

1.6.3 Schemas
A schema is a collection of named objects. The named objects can include distinct types, functions, stored procedures, sequences, and triggers. An object is assigned to a schema when it is created. The schema name of the object determines the schema to which the object belongs. When a distinct type, function, sequence, or trigger is created, it is given a qualified, two-part name. The first part is the schema name (or the qualifier), which is either implicitly or explicitly specified. The second part is the name of the object. When a stored procedure is created, for example, it is given a three-part name. The first part is a location name, which is implicitly or explicitly specified; the second part is the schema name, which is implicitly or explicitly specified; and the third part is the name of the object. Schemas extend the concept of qualifiers for tables, views, indexes, and aliases to enable the qualifiers for distinct types, functions, stored procedures, sequences, and triggers to be called schema names. Note: The qualifier, or owner of a table name, can also be considered a schema name, even though no explicit CREATEIN authorization is required to create a table with a specific qualifier.

1.7 Accessing DB2 from a Java environment


Java Database Connectivity (JDBC) and embedded SQL for Java (SQLJ) are the two standards-based Java application programming interfaces (APIs) supported by DB2. JDBC is part of the J2EE standard. The Java 2 Platform, Enterprise Edition (J2EE) is a specification of the different technologies that are available to developers of enterprise Java applications. Typically these applications are server based, and may even include multiple
Chapter 1. Introduction to DB2 for z/OS and OS/390

19

servers of different types. This server focus makes it the architecture of interest for DB2 for OS/390 and z/OS developers. JDBC defines the standard Application Programming Interface (API) for accessing relational database systems, such as DB2, from Java. This API is the fundamental building block for writing DB2 Java applications. The SQLJ specification is currently not part of the J2EE standard, but is an ISO/ANSI standard. It consists of the following parts: Part 10 specifies the SQLJ language syntax and semantics for embedded SQL statements in a Java application. American National Standards Institute (ANSI) has accepted this part of the SQLJ specification for standardization (document number ISO/IEC 9075-10:2000). The International Standards Organization (ISO) has accepted the SQLJ specification, Part 10. Part 13 specifies extensions that define: Installation of Java classes in a relational database Invocation of Java static methods as SQL stored procedures or functions SQL:2003-conforming object data types and extensions for accessing Java classes as SQL structured types ANSI has accepted Part 13 of the SQLJ specification for standardization (document number ISO/IEC 9075-13:2002). DB2 UDB for z/OS Version 8 support for SQLJ includes Part 10 of the SQLJ specification and a subset of Part 13. Both JDBC and SQLJ can be used to create Java applications and applets that access DB2. DB2s support for JDBC allows Java applications to access local DB2 data or remote relational data on a server that supports Distributed Relational Database Architecture (DRDA). Java applications use SQLJ for static SQL and JDBC for dynamic SQL to access any relational database. SQLJ applications exploit JDBC as an underlying foundation for tasks such as connecting to databases and handling SQL errors. This allows SQLJ to inter-operate with JDBC, making it possible for an application program to use JDBC and SQLJ within the same unit of work.

1.7.1 JDBC fundamentals


The JDBC API specification was developed by Sun Microsystems together with relational database providers, such as IBM and Oracle, to ensure the portability of Java applications across databases and platforms. There have been three major releases of the JDBC API specification to date. The most recent one, at the time of writing this publication, is the JDBC 3.0 specification. The final JDBC 3.0 specification was released in February 2002. However, a JDBC 4.0 specification was filed in 2003. In order to access relational data from a Java application, it is essential to understand the industry standard JDBC API. In fact, connecting to a database, running SQL statements and processing data occurs through the JDBC layer. The purpose of the JDBC API is to provide a generic interface for writing platform-independent Java applications that can access, but is not limited to, any relational database. One key element of the JDBC API specification is backward compatibility. This allows Java applications that use only features defined in earlier JDBC specifications, excluding depreciated APIs, to easily migrate to the latest JDBC technology without having to make any changes to continue running. 20
DB2 for z/OS and WebSphere: The Perfect Couple

The most current information on the latest JDBC specification available and future developments can be obtained at the following Sun Microsystems Web site:
http://java.sun.com/products/jdbc/

1.7.2 JDBC driver types


The role of the JDBC driver is to implement the objects, methods, and data types defined in the JDBC specification. There are currently four JDBC driver types defined in the JDBC 3.0 specification. Important: Although the JDBC driver types are numbered in ascending order from 1 to 4, this does not have any meaning in terms of versioning, nor does it represent an enhancement from one driver to the next. They are four unique types of drivers.

Type 1
Commonly referred to as the JDBC-ODBC bridge driver, type 1 drivers map the JDBC API to another data access API, such as ODBC. Type 1 JDBC drivers are limited in portability because of the fact that they are generally dependent on a native library. The overhead involved in having to use two APIs (JDBC and ODBC) degrades performance. DB2 for z/OS does not supply a type 1 driver.

Type 2
Type 2 drivers are written partly in the Java programming language and partly in native code. These drivers use a native client library specific to the data source to which they connect. Although portability is limited due to the platform-specific native code, the type 2 driver is currently the most commonly used driver type, as it provides the best performance when local to the database. DB2 UDB for OS/390 and z/OS offers two type 2 drivers: IBM DB2 JDBC/SQLJ 2.0 Driver, also known as the IBM DB2 Legacy Driver IBM DB2 Universal Driver for SQLJ and JDBC

Type 3
A type 3 driver is a driver that is written in pure Java. With the type 3 driver, a Java client is used to communicate with a middleware server using a network-specific protocol. The middleware server translates the client request in order to access the data source. DB2 for OS/390 and z/OS does not supply a type 3 driver.

Type 4
Type 4 drivers are written in pure Java and implement the database protocol for a specific data source. The client connects directly to the data source. DRDA is the protocol that is used when connecting to a DB2 system as a data source. The type 4 driver is fully portable since it is written purely in Java. The DB2 Universal Driver supports type 4 connectivity. Additional information on JDBC driver types and the different scenarios when they can/should be used is available in the DB2 for z/OS and OS/390: Ready for Java, SG24-6435.

Chapter 1. Introduction to DB2 for z/OS and OS/390

21

1.7.3 IBM DB2 Legacy Driver


A DB2 JDBC type 2 driver, referred to as the DB2 JDBC Legacy type 2 driver, was introduced to DB2 UDB for OS/390 Version 6 via the maintenance stream in APAR PQ36011. DB2 UDB for z/OS and OS/390 Version 7 integrated the DB2 JDBC Legacy type 2 driver into the base code. DB2 UDB for z/OS Version 8 still ships the legacy driver for compatibility reasons, but V8 also ships the IBM DB2 Universal Driver for SQLJ and JDBC. Tip: The latest maintenance level for the DB2 JDBC Legacy type 2 driver for all currently supported versions of DB2 UDB for OS/390 and z/OS, at the time of writing this publication, is APAR PQ90211 for V8, PQ90210 for V7, and PQ90208 for V6. The DB2 JDBC Legacy Type 2 driver should not be confused with the JDBC type 2 driver provided with the IBM DB2 Universal Driver. They are not the same driver. In fact, they are very different. Some of the JDBC and SQLJ differences between the drivers are discussed in Differences between the DB2 Universal Driver and DB2 Legacy Driver on page 31. Best practice: Transition from DB2 Legacy Driver type 2 connectivity to the type 2 connectivity provided by the IBM DB2 Universal Driver is highly recommended.

1.8 IBM DB2 Universal Driver for SQLJ and JDBC


The IBM DB2 Universal Driver for SQLJ and JDBC is a unique architecture-neutral JDBC driver that supports JDBC type 2 and JDBC type 4 connectivity as well as SQLJ for distributed and local access. The DB2 Universal Driver is not based on any previous DB2 JDBC drivers. It is a completely new driver that is not categorized by the conventional driver types. This driver is also known as the DB2 Universal Driver for Java Common Connectivity (JCC). When the DB2 Universal Driver is loaded by a Java application, a single driver instance is created, providing JDBC type 2 and type 4 driver connectivity. Figure 1-6 on page 23 illustrates the Java application flow with DB2 Universal Driver type 2 and type 4 connectivity. How a connection to a data source is made depends on the JDBC specification level being used. The DriverManager interface is available for all levels of JDBC. The DataSource interface is available with JDBC 2.0 and later. Type 4 connectivity with the Universal Driver uses DRDA to connect to a database server (remote or local). This means that when using type 4 connectivity, DDF will be used even when a Java program runs on the same z/OS system or logical partition (LPAR) as the target DB2 subsystem. To avoid using DDF and the associated network overhead, we recommend using type 2 connectivity with the DB2 Universal Driver when a Java application is accessing a local DB2 subsystem. The Universal Driver also supports distributed transaction management (two-phase commit support) in the z/OS environment when type 2 or type 4 connectivity is used. However, there is a difference when using type 2 or type 4 connectivity for two-phase commit transactions. When using type 2 connectivity for distributed transactions, RRS is used as the transaction manager. In the case of type 4 connectivity for distributed transactions, there is no need for RRS, as this is handled by the type 4 (XA) driver. Type 4 connectivity with distributed transaction support (two-phase commit) is bundled with DB2 for z/OS; IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 (see also 1.8.1, IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 on page 24); and DB2 UDB for Linux, UNIX, and Windows Version 8 FixPak 5 or later. 22
DB2 for z/OS and WebSphere: The Perfect Couple

More details on JDBC and SQLJ Universal Driver Type 4 XA connectivity distributed transaction support are also documented in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414. The IBM DB2 Universal JDBC Driver (containing type 2, type 4, and type 4 XA support) is shipped as an optional installable Function Module Identifier (FMID) JDB8812 with DB2 UDB for z/OS Version 8. For DB2 UDB for OS/390 and z/OS Version 7, APAR PQ80841 delivers the IBM DB2 Universal JDBC Driver under FMID JDB7712. Tip: The latest maintenance level for the IBM DB2 Universal Driver for SQLJ and JDBC, at the time of writing this publication, is APAR PQ95284.

Attention: The DB2 JDBC Legacy Driver is also packaged in FMID JDB7712 in a DB2 UDB for OS/390 and z/OS Version 7 environment, and FMID JDB8812 in a DB2 UDB for z/OS Version 8 environment. However, the HFS sub-directories used for the Universal Driver and the Legacy Driver are different.

Java application

DriverManager or DataSource

IBM DB2 JDBC Universal Driver

Type 2 connectivity
DDF
Local DB2 subsystem
DRDA (potential)

Type 4 connectivity using DRDA


DDF
Remote DB2 subsystem

Figure 1-6 IBM DB2 Universal JDBC Driver type 2 and type 4 connectivity

Chapter 1. Introduction to DB2 for z/OS and OS/390

23

Java 2 Technology Edition, SDK 1.3.1 or later is required to use the IBM DB2 Universal JDBC Driver. At the time of writing this publication, the DB2 Universal Driver supports the following JDBC and SQLJ functions: All methods described in the JDBC 1.2 and JDBC 2.0 specifications. Most methods described in the JDBC 3.0 specification SQLJ statements that perform equivalent functions to all JDBC methods Implementation of Java user-defined functions and stored procedures (Universal Driver type 2 connectivity only) Global transactions that run under WebSphere Application Server Version 5.02 (with APAR PQ80079) and later Distributed transaction support that implements the Java 2 Platform, Enterprise Edition (J2EE) Java Transaction Service (JTS) and Java Transaction API (JTA) specifications (Universal Driver type 4 connectivity to DB2 UDB for OS/390 Version 7 or DB2 UDB for z/OS Version 8)

1.8.1 IBM z/OS Application Connectivity to DB2 for z/OS and OS/390
IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 is a no-charge, optional feature of DB2 Universal Database Server for OS/390 and z/OS Version 7 and DB2 UDB for z/OS Version 8. The purpose of this feature is to deliver connectivity for Java-based enterprise applications on z/OS to a remote DB2 for z/OS database server. The driver: Implements JDBC 3.0 specifications and SDK 1.3.1 or SDK 1.4.1 to deliver the maximum flexibility and performance required for enterprise applications Delivers robust connectivity to the latest DB2 for z/OS and WebSphere Application Server for z/OS Provides Type 4 connectivity with XA distributed transaction support (two-phase commit) Allows custom Java applications that do not require an application server to run in a remote partition and connect to DB2 z/OS Attention: The IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 feature provides connectivity from a z/OS or OS/390 remote partition or system only. For access from any other operating system or platform, including z/Linux, to DB2 for z/OS and OS/390, you must obtain a separate license for the edition of DB2 Connect that is appropriate for your environment. Using JDBC Type 2 driver connectivity to access data on a remote DB2 subsystem requires a local DB2 subsystem to act as a request router (DRDA application requester). When using the type 4 connectivity provided by the z/OS Application Connectivity feature, the dependency on a local DB2 subsystem for the sole purpose of routing requests to access data on a remote DB2 subsystem is eliminated. As illustrated in Figure 1-7 on page 25, this is accomplished by the JDBC type 4 XA driver using the DRDA protocol to connect directly to the DDF address space of the remote DB2 subsystem. You must have a DB2 UDB for OS/390 and z/OS Version 7 or Version 8 license to order this no-charge feature. Other facts related to the IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 feature are: It is packaged under FMID HDDA210. Having an exclusive FMID allows the feature to be installed independently on any given z/OS system or LPAR without having to install an entire DB2 subsystem.

24

DB2 for z/OS and WebSphere: The Perfect Couple

It can be used to access data on a DB2 UDB server for OS/390 Version 6 subsystem. However, certain technical limitations apply. For example, XA two-phase commit functionality is not supported. DB2 UDB for OS/390 and z/OS Version 7 does not have built-in support for distributed transactions that implement the XA specification. 1.9.4, DB2T4XAIndoubtUtil utility for DB2 UDB for OS/390 and z/OS Version 7 on page 30, discusses how it is still possible to include DB2 V7 subsystems in transactions involving two-phase commit processing. In addition, Chapter 8, Transaction management in a WebSphere environment on page 191, discusses best practices related to distributed transactions. DB2 UDB for z/OS Version 8 has native XA support in DRDA allowing two-phase commit processing.

z/OS
Unix System Services (USS)
IBM DB2 for z/OS Application Connectivity
(DB2 Universal JDBC Driver provided by FMID HDDA210)

z/OS
DB2 UDB for z/OS V8
Type 4 (XA or non-XA) via DRDA

WebSphere Application Server

DDF

z/OS
USS

Type 4 (XA or non-XA) via DRDA(*)

DRDA to remote DB2

DDF
WebSphere Application Server DB2 Universal JDBC Driver
(DB2 JDBC Universal Driver provided by FMID JDB8812)

Type 4
Possible but NOT recommended

Type 2 to local DB2

DB2 UDB for z/OS V8

Figure 1-7 DB2 z/OS Application Connectivity and DB2 Universal Driver implementations

Chapter 1. Introduction to DB2 for z/OS and OS/390

25

1.9 Using the DB2 Universal Driver for SQLJ and JDBC
The package name of the DB2 Universal Driver is com.ibm.db2.jcc.DB2Driver. The package is contained in the db2jcc.jar file. File db2jcc.jar contains the JDBC driver and SQLJ run time. File sqlj.zip contains the reference implementation of the standard SQLJ precompiler. It contains the classes that are needed to prepare SQLJ applications for execution under the DB2 Universal JDBC Driver. The HFS directory of the DB2 Universal Driver files is dependent on the product that provided the driver: HFS directory for DB2 UDB for OS/390 and z/OS Version 7 During DB2 V7 installation, the DB2 Legacy JDBC Driver default directory usr/lpp/db2/db2710/ is created when job hlq.SDSNBASE(DSNISMKD) is run. When APAR PQ80841 is applied to a DB2 V7 subsystem delivering the DB2 Universal Driver, default directory usr/lpp/db2/db2710/jcc/ is created. HFS directory for DB2 UDB for z/OS Version 8 During DB2 V8 installation, the DB2 Legacy JDBC Driver default directory usr/lpp/db2810/ as well as DB2 Universal Driver default directory usr/lpp/db2810/jcc/ is created by job hlq.SDSNBASE(DSNISMKD). HFS directory for IBM z/OS Application Connectivity to DB2 for z/OS During product installation, running hlq.SDDABASE(DDAISMKD) creates the default directory usr/lpp/jcct4 for the DB2 Universal Driver.

1.9.1 Required environment variable settings


There are three environment variables that are required to be set before using the DB2 Universal Driver. In z/OS UNIX System Services, the .profile file can be used to customize the environment variable settings. Specifically, the libraries, paths, and files that the Universal Driver uses need to be added. The environment variables that must be set are: PATH This directory contains the shell scripts that invoke JDBC and SQLJ program preparation and debugging functions needs to be included in the PATH. These functions reside in the /bin sub-directory of the default installation path used. The export statement is used to add the appropriate directory to the PATH environment variable. Example 1-4 provides sample export statements using the default installation directories. Only one export statement is required in the .profile, depending on which installation is being used.

Example 1-4 Sample export statements for the PATH environment variable If using DB2 UDB for z/OS Version 8: export PATH=/usr/lpp/db2810/jcc/bin:$PATH If using z/OS Application Connectivity to DB2 for z/OS: export PATH=/usr/lpp/jcct4/bin:$PATH If using DB2 UDB for OS/390 and z/OS Version 7: export PATH=/usr/lpp/db2/db2710/jcc/bin:$PATH

LIBPATH

The DB2 Universal Driver requires native (C or C++) dynamic load libraries (DLLs) to be available when using type 2 connectivity. The DLLs are provided with the driver and reside in the /lib sub-directory.

26

DB2 for z/OS and WebSphere: The Perfect Couple

To include the directory that contains these DLLs to the LIBPATH environment variable, the export statement is used. Example 1-5 provides sample export statements using the default installation directories. Only one export statement is required in the .profile, depending on which installation is being used.
Example 1-5 Sample export statements for the LIBPATH environment variable If using DB2 UDB for z/OS Version 8: export LIBPATH=/usr:/usr/lib:/usr/lpp/db2810/jcc/lib:$LIBPATH If using z/OS Application Connectivity to DB2 for z/OS: export PATH=/usr/lpp/jcct4/bin:$PATH If using DB2 UDB for OS/390 and z/OS Version 7: export LIBPATH=/usr:/usr/lib:/usr/lpp/db2/db2710/jcc/lib:$LIBPATH

CLASSPATH

The DB2 Universal Driver requires four class files to be in the CLASSPATH environment variable. These class files reside in the /classes sub-directory. They are: This file contains all JDBC classes and the SQLJ run-time classes for the DB2 Universal JDBC Driver. This file contains a subset of the J2EE classes that are needed by the DB2 Universal Driver. This file contains the classes that are needed to prepare SQLJ applications for execution under the DB2 Universal Driver. This file is the license which permits access to the DB2 for z/OS server.

db2jcc.jar db2jcc_javax.jar sqlj.zip

db2jcc_license_cisuz.jar

To include these files in the CLASSPATH environment variable, the export statement is used. Example 1-6 provides sample export statements using the default installation directories. Only one export statement is required in the .profile, depending on which installation is being used.
Example 1-6 Sample export statements for the CLASSPATH environment variable If using DB2 UDB for z/OS Version 8: export CLASSPATH=/usr/lpp/db2810/jcc/classes/db2jcc.jar:\ /usr/lpp/db2810/jcc/classes/db2jcc_javax.jar:\ /usr/lpp/db2810/jcc/classes/sqlj.zip:\ /usr/lpp/db2810/jcc/classes/db2jcc_license_cisuz.jar:$CLASSPATH If using z/OS Application Connectivity to DB2 for z/OS: export CLASSPATH=/usr/lpp/jcct4/classes/db2jcc.jar:\ /usr/lpp/jcct4/classes/db2jcc_javax.jar:\ /usr/lpp/jcct4/classes/sqlj.zip:\ /usr/lpp/jcct4/classes/db2jcc_license_cisuz.jar:$CLASSPATH If using DB2 UDB for OS/390 and z/OS Version 7: export CLASSPATH=/usr/lpp/db2/db2710/jcc/classes/db2jcc.jar:\ /usr/lpp/db2/db2710/jcc/classes/db2jcc_javax.jar:\ /usr/lpp/db2/db2710/jcc/classes/sqlj.zip:\ /usr/lpp/db2/db2710/jcc/classes/db2jcc_license_cisuz.jar:$CLASSPATH

Chapter 1. Introduction to DB2 for z/OS and OS/390

27

1.9.2 DB2 Universal Driver stored procedures and metadata


Metadata is a term used to describe characteristics of data. The phrase data about data is generally used to define metadata. For our purposes, metadata refers to information used to describe data objects that can be retrieved from the DB2 catalog. The JDBC API allows applications to retrieve database metadata. This metadata fall into three broad categories: Information about the JDBC driver such as driver name, major and minor version Information about the database server such as the supported SQL level and handling of NULL values Information about database objects such as number of columns in a table, column names, and the column data type The metadata is usually retrieved by specifying the schema associated with the desired data objects. Additional details about DB2 catalog metadata and how to retrieve specific information is documented in DB2 for z/OS and OS/390: Ready for Java, SG24-6435. Certain functions of the DB2 Universal Driver expect metadata to be available. In fact, the metadata is also expected to be in a particular format. This is consistent with the schema metadata APIs documented in the JDBC and ODBC specifications. This section discusses required DB2 for OS/390 and z/OS functionality when using the DB2 Universal Driver.

DESCRIBE for static SQL statements


The SQL statement DESCRIBE obtains information about a prepared statement, a table, or a a view. There are some restrictions when using the DESCRIBE statement, such as: It can only be embedded in an application program. It cannot be dynamically prepared. It cannot be specified in Java. An SQL descriptor area (SQLDA) is required. The SQLDA is simply a collection of variables and its layout is described in Appendix E of DB2 Universal Database for z/OS Version 8 SQL Reference, SC18-7426. The DB2 Universal Driver expects the SQLDA to be available when using SQL statements. By default, a DESCRIBE (OUTPUT) can only be used against dynamically prepared statements. To resolve this problem, a new DSNZPARM parameter, DESCSTAT, was introduced. It allows the driver to issue DESCRIBE statements against statically bound statements as well. When set to YES, DESCSTAT generates a DESCRIBE SQLDA at bind time, allowing DESCRIBE requests for static SQL to be satisfied during execution. When DESCSTAT is set to YES, packages will slightly increase in size because the DESCRIBE SQLDA is now stored with each statically bound SQL SELECT statement. DB2 UDB for OS/390 Version 6 and DB2 UDB for OS/390 and z/OS Version 7 have a default value of NO for option DESCRIBE FOR STATIC on installation panel DSNTIPF. (This is the option associated with DSNZPARM DESCSTAT). Modify DSNZPARM DESCSTAT to YES in member DSNTIJUZ in the DB2 hlq.SDSNSAMP library. DSNTIJUZ is used to perform DB2 DSNZPARM updates. Generally, to pick up subsystem changes to DSNZPARM parameters after running DSNTIJUZ, the DB2 subsystem would have to be recycled by stopping and starting DB2. However, DESCSTAT is a DSNZPARM that can be updated online. This means the SET SYSPARM LOAD(dsnzparm_name) command can be used as a less disruptive alternative to refreshing DB2 subsystem parameters to pick up the change.

28

DB2 for z/OS and WebSphere: The Perfect Couple

The complete list of DB2 subsystem parameters that can be updated online is documented in Appendix C of DB2 Universal Database for z/OS Version 8 Installation Guide, GC18-7418. In DB2 UDB for z/OS Version 8, the default value for the DESCRIBE FOR STATIC option on installation panel DSNTIP4 (DSNZPARM DESCSTAT) is YES for new installations (not when you migrate an existing subsystem). Important: It is imperative to rebind all packages that intend to use the DESCRIBE SQLDA generated by the DESCSTAT DSNZPARM after changing to DESCSTAT=YES.

Metadata requirement using DB2 UDB for OS/390 and z/OS V6 and V7
The metadata availability and uniform view specification the DB2 Universal Driver requires is delivered by APAR PQ62695 for DB2 UDB for OS/390 Version 6 and DB2 UDB for OS/390 and z/OS Version 7 environments. APAR PQ62695 modifies installation job stream member DSNTIJMS to create 13 stored procedures as well as tables, views, and user-defined indexes (on the DB2 catalog) used by the stored procedures. These stored procedures allow the DB2 JDBC Universal Driver to retrieve schema-based catalog metadata. DSNTIJMS resides in the DB2 hlq.SDSNSAMP library. Important: Before running DSNTIJMS, make sure that DSNZPARM DESCSTAT is set to YES.

Attention: APARs PQ72453, PQ78165, and PQ83561 should also be applied to resolve initial implementation errors in APAR PQ62695. This functionality is also required when using the DB2 Universal Driver (as well as the ODBC driver) to connect to a DB2 OS/390 or z/OS subsystem from a Linux, UNIX, or Windows V8 platform. SYSADM authority is not required to install the metadata stored procedures.

Metadata requirement using DB2 UDB for z/OS V8


Contrary to previous versions, DSNZPARM DESCSTAT is set to YES by default when installing a DB2 UDB for z/OS Version 8 from scratch. Maintenance is not required to deliver JDBC and ODBC metadata method support, as the DSNTIJMS member of hlq.SDSNSAMP is included with the DB2 UDB for z/OS Version 8 base product. Once the necessary stored procedures have been created by DSNTIJMS and packages have gone through the bind process (with DESCSTAT set to YES), stored procedures will be able to retrieve the metadata from the DB2 catalog. SYSADM authority is not required to install the metadata stored procedures.

1.9.3 Binding DB2 Universal JDBC Driver packages with the DB2Binder utility
The DB2Binder utility is a component of the DB2 Universal Driver that binds the driver packages and grants EXECUTE authority on the packages to PUBLIC. Assume a DB2 UDB for z/OS Version 8 subsystem has the following settings: A host name wtsc54.itso.ibm.com Uses port 38070 A DB2 location name of DBD8

Chapter 1. Introduction to DB2 for z/OS and OS/390

29

The DB2Binder utility can be run using the syntax shown in Example 1-7 on a z/OS UNIX System Services command line.
Example 1-7 Running the DB2Binder utility java com.ibm.db2.jcc.DB2Binder -url jdbc:db2://wtsc54.itso.ibm.com:38070/DBD8 \ -user SYSADM -password mypass

1.9.4 DB2T4XAIndoubtUtil utility for DB2 UDB for OS/390 and z/OS Version 7
Although native support for two-phase commit transactions does not exist for DB2 UDB for OS/390 and z/OS Version 7 subsystems, they can be included in distributed transactions using the type 4 Universal Driver after running the DB2T4XAIndoubtUtil utility against those V7 servers. This utility allows DB2 UDB for OS/390 and z/OS Version 7 servers to emulate distributed transaction (two-phase commit) support when using Type 4 XA connectivity. You will not find the DB2T4XAIndoubtUtil utility in an HFS directory. It is not a file. It is a component of the DB2 Universal Driver. The utility is used to create a table named SYSIBM.INDOUBT. This table stores information about in-doubt global transactions. In addition, the utility also binds a package named T4XAIndbtPkg. This package contains SQL statements used to insert, delete, and read rows from the SYSIBM.INDOUBT table. Assume a DB2 UDB for OS/390 and z/OS Version 7 subsystem has the following settings: IP address of 9.12.4.26 Uses port 38060 DB2 location name of DBD7 A user with SYSADM authority, which is required to run this utility, can run the DB2T4XAIndoubtUtil utility using the syntax shown in Example 1-8 on a z/OS UNIX System Services command line.
Example 1-8 Running the DB2T4XAIndoubtUtil utility java com.ibm.db2.jcc.DB2T4XAIndoubtUtil -url jdbc:db2://9.12.4.26:38060/DBD7 \ -user SYSADM -password mypass

Tip: The IP address or domain name, port, and DB2 location name can be determined by issuing the -DISPLAY DDF command, or by finding the DSNL004I message in ssnmMSTR of the DB2 UDB for OS/390 and z/OS Version 7 subsystem. If finding a user with SYSADM authority to run the DB2T4XAIndoubtUtil program is a problem, and you have the PTF for APAR PQ95881 installed, you can create the SYSIBM.INDOUBT table manually, and use the new -bindonly option of the DB2T4XAIndoubtUtil program to bind the required packages. When you use the -bindonly option, it is sufficient to have BIND authority; SYSADM is not required in that case. APAR PQ95881 adds two options to the DB2T4XAIndoubtUtil program: -bindonly When this option is specified, DB2 does not create the SYSIBM.INDOUBT table (which requires SYSADM authority). It only binds the T4XAIndbtPkg package. The SYSIBM.INDOUBT table can be created by executing the sample SQL shown in Example 1-9.

Example 1-9 DDL to create the SYSIBM.INDOUBT table CREATE TABLESPACE INDBTTS USING STOGROUP ...

30

DB2 for z/OS and WebSphere: The Perfect Couple

LOCKSIZE ROW BUFFERPOOL BP0 SEGSIZE 32 CCSID EBCDIC; CREATE TABLE SYSIBM.INDOUBT ( indbtXid VARCHAR(140) ,uowId VARCHAR(25) FOR ,pSyncLog VARCHAR(150) ,cSyncLog VARCHAR(150) FOR BIT FOR FOR BIT DATA NOT NULL DATA NOT NULL BIT DATA BIT DATA) IN INDBTTS;

CREATE UNIQUE INDEX INDBTIDX ON SYSIBM.INDOUBT(indbtXid, uowId);

-jdbcCollection

<Collection name for JCC packages>. If the JDBC (dynamic) packages were bound (using the DB2Binder program) with a collection name other than "NULLID", then you must specify that collection name using the -jdbcCollection option, so that the DB2T4XAIndoubtUtil program can prepare its dynamic statements correctly.

Additional details on the DB2T4XAIndoubtUtil utility are documented in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

1.9.5 Differences between the DB2 Universal Driver and DB2 Legacy Driver
There are a number of fundamental differences between the IBM DB2 Legacy Driver and the IBM DB2 Universal JDBC Driver. A handful of these differences when using JDBC and SQLJ with the different drivers are listed in Table 1-3 and Table 1-4 on page 32.
Table 1-3 JDBC differences between the DB2 Universal Driver and the DB2 Legacy Driver JDBC functionality Scrollable and updatable ResultSets Read-only connections IBM DB2 Universal Driver Supports scrollable and updatable ResultSets A read-only connection can be made through the readOnly property for a Connection or DataSource object Returns data from a ResultSet.getString call for a CHAR FOR BIT DATA or VARCHAR FOR BIT DATA column as a lowercase hexadecimal string Uses LOB locators internally under the following circumstances: Always, for fetching data from scrollable cursors Never, for fetching data from stored procedure result sets If the fullyMaterializeLobData connection property is set to true, in all other cases IBM DB2 Legacy Driver Supports only non-scrollable and non-updatable ResultSets Does not support read-only connections

Results returned from ResultSet.getString for a BIT DATA column

Returns the data in the encoding scheme of the caller

Internal use of LOB locators

Does not use LOB locators

Chapter 1. Introduction to DB2 for z/OS and OS/390

31

Table 1-4 SQLJ differences between the DB2 Universal Driver and the DB2 Legacy Driver SQLJ functionality Scrollable and updatable iterators SQLJ program preparation IBM DB2 Universal Driver Supports scrollable and updatable iterators. Additional SQLJ translator parameters when translating source program-name.sqlj files to serialized profiles. Customize serialized profiles with the db2sqljcustomize command. By default, db2sqljcustomize automatically binds four (one for each isolation level) DB2 packages (DBRMs are not generated as output). If automatic bind was not performed by the db2sqljcustomize command, the db2sqljbind utility should be used to bind packages. A plan is not required. Using the DataSource interface to connect to a data source Before you can use a default connection context, the logical name jdbc/defaultDataSource must be registered with the Java Naming and Directory Interface (JNDI). IBM DB2 Legacy Driver Supports only non-scrollable and non-updatable iterators. Fewer SQLJ translator parameters. Customize serialized profiles with the db2profc command. Four DBRMs (one for each DB2 isolation level) and customized serial profiles are generated as output. You can bind the DBRMs directly into a plan or bind the DBRMs into packages and then bind the packages into a plan. Additionally, the four JDBC packages named DSNJDBC.DSNJDBCx by default must also be bound into the SQLJ plan. Creates a connection to the local data source for the default connection context.

The complete list of differences is in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

1.9.6 JDBC 3.0 APIs specific to the DB2 Universal Driver


There are a number of new JDBC APIs introduced with the JDBC 3.0 specification that are only available when using the DB2 Universal Driver. To use these methods, you must cast an instance of the related standard JDBC class to an instance of the DB2-only class, as depicted in Example 1-10.
Example 1-10 Casting an instance of the JDBC class to an instance of the DB2-only class javax.sql.DataSource ds = new com.ibm.db2.jcc.DB2SimpleDataSource(); ((com.ibm.db2.jcc.DB2BaseDataSource) ds).setServerName("wtsc54.itso.ibm.com");

A few of the interfaces and methods that can only be used with the DB2 Universal Driver are listed in Table 1-5 on page 33.

32

DB2 for z/OS and WebSphere: The Perfect Couple

Table 1-5 JDBC APIs specific to the DB2 Universal Driver Interface DB2Connection Method getDB2CurrentPackagePath Result Returns a list of DB2 package collections, which are searched for when looking for the DB2 Universal JDBC Driver packages or SQLJ packages. Specifies a list of collection IDs that DB2 searches when looking for the DB2 Universal JDBC Driver DB2 packages. Returns the collection ID for the connection. Specifies the collection ID for the connection. When you set this value, you also set the collection ID of the DB2 Universal JDBC Driver instance that is used for the connection. Returns the current trace destination for the DB2 Universal Driver. Enables or disables the DB2 Universal Driver trace, or changes the trace destination during an active connection. Returns a DB2Sqlca object from a java.sql.Exception that is produced by the DB2 Universal Driver. Prints diagnostic information after a java.sql.Exception is thrown under a DB2 Universal Driver. Converts a com.ibm.jcc.DB2RowID object to bytes. Returns error message text. Returns an SQL error code value. Returns the SQLCA SQLSTATE value.

setDB2CurrentPackagePath

getDB2CurrentPackageSet setDB2CurrentPackageSet

getJccLogWriter setJccLogWriter

DB2Diagnosable

getSqlca

printTrace

DB2RowID DB2Sqlca class

getBytes getMessage getSqlCode getSqlState

The complete list of supported methods is documented in DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

Chapter 1. Introduction to DB2 for z/OS and OS/390

33

34

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 2.

Introduction to WebSphere for z/OS


This chapter provides a brief overview of Java 2 Enterprise Edition (J2EE), including the J2EE architecture, application components and their corresponding containers, platform roles, as well as the benefits of the J2EE environment. In this chapter we also provide a brief introduction to the WebSphere Application Server (WAS) V5.0.2 that is the premier J2EE-based application platform on z/OS, offering a solid production-ready server for running enterprise applications. This chapter contains the following topics: Java 2 Enterprise Edition (J2EE) overview WebSphere Application Server architecture WebSphere Application Server administration The WebSphere family WAS 5.0.2 features and J2EE support

Copyright IBM Corp. 2005. All rights reserved.

35

2.1 Java 2 Enterprise Edition (J2EE) overview


The Java 2 Enterprise Edition (J2EE) specification is a standard for developing, assembling, deploying, running, and managing multi-tier server-centric enterprise applications. The specification applies to all aspects of the architecture and development of large-scale enterprise applications. J2EE encourages the adoption of a multi-tier architecture and a strict separation between business logic and presentation. Along with the specification, J2EE consists of a Compatibility Test Suite that is used to verify that a specific product complies with the J2EE specifications. IBM WebSphere Application Server Version 5 is a fully J2EE-compliant product. It has completed the full J2EE certification test suite, and exceeds many of the requirements with its extensions. Figure 2-1 shows the basic J2EE architecture, the multi-tier approach, and the logical relationships between the components.

Tier 0
Applet Container Applet

Tier 1
Web Container JSP Servlet

Tier 2
EJB Container EJB

Tier 3
Enterprise Information System DB2 CICS

Application Client Container Application

Client side tier


Figure 2-1 J2EE architecture

Server side tiers

J2EE roles
J2EE also defines a set of roles that apply to various steps in the entire development, deployment, and maintenance life-cycle. The roles help identify the tasks and people involved, and who is responsible for the different tasks. Product provider is the implementor and supplier of a J2EE product that includes the component containers, J2EE platform APIs, and other features defined in the J2EE specification. IBM is a provider with, for instance, WebSphere Application Server and DB2. Application component provider is the creator of Web components, enterprise Beans, or enterprise applications. Application assembler takes a set of components developed by the application component providers and assembles them into an enterprise application archive.

36

DB2 for z/OS and WebSphere: The Perfect Couple

Deployer is responsible for deploying the enterprise application into the operational environment. This typically means to install, configure, and start the enterprise application on the application server. System administrator is responsible for the operational environment in which the enterprise application runs, including the network infrastructure. Tool provider provides tools used for the development and packaging of application components. IBM is a tool provider with the WebSphere Studio Application Developer (WSAD) suite. Note: Starting with Version 6 that became available in December 2004, WSAD also has a new name, and is now called IBM Rational Application Developer for WebSphere Software. However, since this publication was written using Version 5, we still use the term WSAD throughout this book. You can group these roles into three categories. The product provider and the tool provider have a product focus, while the application component provider and the application assembler focus on the application. Finally the deployer and the system administrator have their focus on the run-time environment. In Figure 2-2 we look at the roles through IBM glasses. The tool used during development and assembly of applications is WebSphere Studio Application Developer (WSAD), while the run-time product is WebSphere Application Server. The component provider uses WSAD to create the components needed for an enterprise application, which is assembled into an Enterprise Application Archive (EAR) file by the application assembler. The EAR file is then handed to the deployer that deploys it. Finally the administrator makes sure it is all up and running smoothly.

To o l P ro v id e r

P ro d u c t P ro v id e r

W SAD

W AS

C om ponent P ro v id e r

A s s e m b le r

D e p lo y e r

A d m in is tra to r

C o m p o n e n ts

E n te rp ris e A p p lic a tio n A rc h iv e

Figure 2-2 J2EE roles with an IBM perspective

The 4-tier programming model


As mentioned earlier, J2EE encourages the adoption of a multi-tier architecture. Note that it is a logical architecture. It is not meant to imply a physical partitioning of the elements into separate machines, address spaces, and so on. As illustrated in Figure 2-1 on page 36, J2EE

Chapter 2. Introduction to WebSphere for z/OS

37

operates with four tiers. Tier 0 is the client-side tier, while the other tiers are referred to as server-side tiers.

The client tier (tier 0)


On this tier are application clients and applets. Application clients are programs written in the Java language and execute on a desktop computer, offering the user an experience similar to that of native applications. Applets are components that typically execute in a Web browser, but they can execute in any environment that supports the applet programming model. Both application clients and applets have access to all of the features of the other tiers.

The Web container (tier 1)


Servlets and JavaServer Pages (JSP) files are used to process requests from HTTP clients, such as Web browsers. They normally handle presentation logic and control of the user interaction with the underlying application data and business logic. If the client is a Web browser, they generate HTML for output, but they can also generate output in other formats, such as XML, for use by other application components. Note: A JSP is in fact just a special type of servlet. When the Application Server loads a JSP, it is translated into a servlet. When handling servlets, the Web container creates a request object and a response object, and then invokes the servlets service method.

The EJB container (tier 2)


The EJB container provides the run-time services needed to deploy and manage enterprise Beans. This is the tier where the business logic is typically implemented. Three types of enterprise Beans exists. Session Beans and message-driven Beans that implement business logic, and entity Beans that represent data. The enterprise Beans do not communicate directly with the server, the EJB container provides an interface between the enterprise Bean and the server. Together, the container and the server provide the Bean run-time environment. The container provides many low-level services, including transaction support and security. A single container can manage more than one EJB jar file.

The Enterprise Information System (tier 3)


The last tier represents the enterprises information system, which can be anything like relational database (RDBMS), IMS, or CICS transactions.

An enterprise application archive, the EAR file


A J2EE application is packaged in an Enterprise Archive, a file with a .EAR extension. The application has a deployment descriptor (DD), allowing configuration to a specific container environment when deployed. The application can include one or more modules, each having its own deployment descriptor. The deployment descriptor contains run-time information about the modules; security is one example. Figure 2-3 on page 39 shows the content of the .EAR file. Basically it consists of these items: Client application modules These modules are packaged in Java Archive (.JAR) files, and are distributed to the client container. Web modules

38

DB2 for z/OS and WebSphere: The Perfect Couple

A Web module groups servlets, JSPs, HTML files, images, and other Web-related files, and is packaged in Web Application Archives (.WAR) files. Web archives are deployed into the Web container. EJB modules EJB modules group related EJBs in a single module, and are packaged in Java Archive (JAR) files. EJB archives are deployed into the EJB container. Resource adapters Resource adapters support access to the Enterprise Information System outside the J2EE server. A resource adapter provides an API for accessing these data, for example, via a CICS resource adapter.

RAR Resource RAR Adapters

J2EE Application .EAR file

Application DD

Client Module .JAR file

Web Module .WAR file

EJB Module .JAR file

Client Class

Client DD

. GIF . Etc. Servlet

EJB EJB JSP

Web DD

EJB EJB EJB

EJB DD

Client Container

Web Container

EJB Container

Figure 2-3 Content of the EAR file

Note: The EAR file can contain an arbitrary number of the described archives, but it does not have to contain them all. In enterprise applications without enterprise Beans, specific client modules or any resource other than a database, only contain Web modules.

J2EE benefits
The J2EE specification provides customers with a standard by which to compare J2EE offerings from vendors and develop applications that run on any J2EE-compliant platform. Comprehensive, independent Compatibility Test Suites ensure vendor compliance with J2EE standards.

Chapter 2. Introduction to WebSphere for z/OS

39

Some benefits of deploying to a J2EE-compliant architecture include: A simplified architecture based on standard components, services, and clients, that takes advantage of the write-once, run-anywhere Java technology. J2EE containers provide for the separation of business logic from resource and life-cycle management, which means that developers can focus on writing business logic and simplify their development. Services providing integration with existing systems, including Java Database Connectivity (JDBC), Java Message Service (JMS), Java Interface Definition Language (Java IDL), the JavaMail API, and Java Transaction API (JTA and JTS) for reliable business transactions. Scalability to meet demand by distributing containers across multiple systems and using database connection pooling, for example. A better choice of application development tools and components from vendors providing standard solutions. A flexible security model that provides single sign-on support, integration with legacy security schemes, and a unified approach to securing application components. The J2EE specifications are the result of an industry-wide effort that involves a large number of contributors. IBM has contributed in defining more than 80 percent of the J2EE APIs.

2.2 WebSphere Application Server architecture


The WebSphere Application Server (WAS) is IBMs implementation of the J2EE server-side environment. It is a Java run-time environment that supports the J2EE architecture. WAS works as a plug-in to the HTTP server. When a request is received by the HTTP server, and the configuration specifies it, the request is forwarded to the application server, as illustrated in Figure 2-4.

Application Client Container

HTTP Server

Websphere Application Server

HTTP request

WAS Plug-in

Web Container

EJB Container

Figure 2-4 WebSphere as a HTTP server plug-in

In WAS for z/OS Version 5, the MVS address space in which the Java Virtual Machine (JVM) resides is called a servant. Multiple servants may be started by WLM, based on work queued by a controller region. Figure 2-5 on page 41 illustrates this.

40

DB2 for z/OS and WebSphere: The Perfect Couple

Server
JCL Controller Region JCL WLM Server Region #2 Java Virtual Machine Server Region #1 Java Virtual Machine

Server Instance CR SR

Figure 2-5 Controllers and servants, the server instance

The structure in the dotted box in Figure 2-5 is known as a server. Throughout this book we use the symbol pointed to by the curved arrow to represent it. On a given z/OS system, or LPAR, a collection of servers is grouped into a node, and a collection of nodes makes up a cell. A cell is the top-level in the WebSphere Application Server architecture. The cell is an administrative domain, or in other words, the boundaries the administrative applications reach. In the next sections we describe different operation environments for WebSphere Application Server. We start out with the simplest environment, then extend to more complex ones.

Base Application Server node


Figure 2-6 shows the simplest operation environment for a WebSphere Application Server, which is the Base Application Server node. It consists of only one node in the cell. The daemon in the figure is used to resolve indirect object references to actual object references, and to distribute the workload between servers. To do this it has to know which servers are active and know the applications in them. A daemon is required, and there has to be one daemon per cell per system or LPAR.

z/OS System or LPAR Cell Node


Daemon Server Instance CR SR Administrative Console

Figure 2-6 Base Application Server node

Chapter 2. Introduction to WebSphere for z/OS

41

The base application server is administered using a browser-based application called the Administrative Console, which is a J2EE application itself. The administrative application is not written to be multi-servant capable; therefore only one servant region must be spawned, when the server runs the administrative application. Note: Throughout this chapter the terms administrative application and the Administrative Console are used interchangeably, whatever applies best. The administrative application is the code running inside WebSphere, while the Administrative Console is the browser-based interface to it. WebSphere for z/OS Version 5 uses an ISPF customization dialog process, called the WebSphere Installer, to create a number of jobs used to install the application server, but that topic is out of the scope of this book. For information about the customization dialog, see WebSphere Information Center at:
http://publib.boulder.ibm.com/infocenter/wasinfo/index.jsp

Or use the link in the Administrative Console.

Multiple Base Application Server nodes


It is possible to install several Base Application Server nodes on the same z/OS system or LPAR, as illustrated in Figure 2-7. It allows us to establish separate run-time environments fairly easy. Each base application server would have its own cell, node, and administrative interface. The administrative application manages just that cell, so administrators in other base application servers cannot touch what is in your base application server. When we want isolated environments for test, development, and so on, we can use separate Base Application Server nodes for that purpose. This provides an excellent setup for isolated environments.

z/OS System or LPAR Cell


Daemon

Node

Server Instance CR SR

Administrative Console

Cell
Daemon

Node

Server Instance CR SR

Administrative Console

Figure 2-7 Multiple Base Application Server nodes

One Base Application Server node with multiple servers


Instead of creating multiple base application nodes, we can stick to one base application node, and then install multiple servers in that node, as shown in Figure 2-8 on page 43. This means that we have only one node and therefore also only one cell. Through the

42

DB2 for z/OS and WebSphere: The Perfect Couple

Administrative Console we can create new servers and install applications within these new servers, thus creating a very flexible environment. As mentioned earlier, only one servant region must be spawned in the server where the administrative application runs. If we want to test our application in a multi-servant environment, this configuration allows us to do so. However, this configuration does not provide us with the same isolation as with multiple Base Application Server nodes. It is possible to install the administrative application in multiple servers, but these instances all have the same privileges within the cell. Any instance is able to install, delete, or modify any application in the other servers.

z/OS System or LPAR Cell Node


Daemon Server Instance A CR SR Administrative Console

Server Instance B CR SR

Figure 2-8 One Base Application Server node with multiple servers

Note: With the Base Application Server node configuration, it is not possible to start and stop servers from within the Administrative Console. This has to be done from the MVS console. The various configurations with the Base Application Server node are great for simple isolated environments. They are good as a first start to learn about WebSphere, and they are good for development, testing, and the like. But in the world of production this configuration is often insufficient. There are several things a base application server cannot do: It must be contained on one z/OS system or LPAR. Servers cannot be stopped and started via the Administrative Console. Servers cannot be grouped into a logical clustered environment for load balancing and failover. This is where network deployment comes into play. It solves the above limitations, even when we only have one z/OS system or LPAR.

Network deployment
We now look at an environment with two z/OS systems, or LPARs, on which we have two servers each, as illustrated in Figure 2-9 on page 44. What we want is to administer these four servers as one from a central location. This can be obtained with the deployment manager, which is a special kind of base application server in which a special version of the administrative application runs. The deployment manager does not interact with the servers directly, it communicates with node agents, which in turn control the servers in the node. This implies that we have one 43

Chapter 2. Introduction to WebSphere for z/OS

node agent for each node. We now have a single cell with multiple nodes that spans systems in a sysplex. The cell is under the management of the deployment manager, and only one deployment manager is permitted per cell, even when the cell spans z/OS systems. Note: The deployment manager is not a single point of failure. If the deployment manager for some reason is unavailable, the only impact is that you are unable to install any applications in the managed servers, or start/stop the servers. The run-time environment is unaffected.

z/OS System or LPAR

z/OS System or LPAR

Cell
Daemon

Deployment Manager

Administrative Console

Daemon

Node 1
Server Instance A CR Node Agent SR

Node 2
Server Instance C CR Node Agent SR

Server Instance B CR SR

Server Instance D CR SR

SYSA

SYSB

Figure 2-9 Two-system sysplex, deployment manager

Note that Figure 2-9 has one cell, but two systems. Therefore, as stated earlier, two daemon servers are required. There are no restrictions in the architecture of WebSphere z/OS that prevent us from having multiple cells in a sysplex. And the cells do not have to span systems; they can be contained entirely within one system. Note: Nodes are created as base application nodes, and then federated into the cell. When a node is added to the cell, the deployment manager can be used to create servers and applications within the added node.

Which configuration to use


The Base Application Server node is best suited for development and test purposes, while the network deployment is preferred in a production environment. Even with one system or LPAR, the network deployment is preferred. Apart from being able to start and stop servers from within the Administrative Console, the most important factor is the flexibility of the environment. It is easy to add another node (using the ISPF interface) for load balancing and failover, for example.

2.3 WebSphere Application Server administration


To administer the WebSphere Application Server several tools are available, but the most important is the Administrative Console.

44

DB2 for z/OS and WebSphere: The Perfect Couple

2.3.1 Administration console


In WebSphere Application Server Version 4, the Administrative Console was a platform-dependent application, but this has changed in Version 5. The Administrative Console for z/OS is now the same as the one used on the distributed platform, which is a major improvement. This makes it much easier to work across different platforms. To access the Administrative Console, the administrative application must first be deployed in WebSphere. Then you access it with the URL http://hostname:9080/admin. In our test environment, the host is wtsc54, making the complete URL http://wtsc54.itso.ibm.com:9080/admin. Note: The port number on your system might differ from 9080, but that is the default port. (The port definition is defined as part of the configuration of your transports.) When you start the Administrative Console, a login dialog is presented, as shown in Figure 2-10.

Figure 2-10 Administrative Console login

After login, the home page of the Administrative Console is shown (Figure 2-11 on page 46). Apart from the possibility to administer the WebSphere Application Server from here, there are a few references to additional support sites: WebSphere Application Server on IBM.com The place for support, including WebSphere Flashes, FAQs, Hints and Tips, and Technotes. You will also find information about downloads, libraries, news, and other useful information. WebSphere Developer Domain Technical articles, best practices, tutorials, and a lot of more in the WebSphere Application Server Zone. Infocenter The complete source for product documentation, including tasks, reference, and conceptual information on product features and functions.

Chapter 2. Introduction to WebSphere for z/OS

45

Figure 2-11 Administrative Console home page

In subsequent chapters of this book we use the Administrative Console to configure our WebSphere Application Server environment. For a detailed description of how to use the Administrative Console, consult IBM WebSphere Application Server V5.0 System Management and Configuration, SG24-6195.

2.3.2 Other tools


Apart from the Administrative Console, there are a number of different tools available for the WebSphere Application Server: Scripting The WebSphere administrative (wsadmin) scripting program is a powerful, non-graphical command interpreter environment enabling you to execute administrative operations in a scripting language. You can also submit scripting language programs for execution. The wsadmin tool is intended for production environments and unattended operations. Commands Command line tools are simple programs that you run from an operating system command line prompt to perform specific tasks, as opposed to general purpose administration. Using the tools, you can start and stop application servers, check server status, add or remove nodes, and complete similar tasks. Programming WebSphere Application Server supports access to the administrative functions through a set of Java classes and methods. You can write a Java program that performs any of the administrative features of the WebSphere Application Server administrative tools.

46

DB2 for z/OS and WebSphere: The Perfect Couple

Further information is available through the Infocenter, accessible from the home page of the Administrative Console, or the Web site:
http://www-306.ibm.com/software/webservers/appserv/zos_os390/library

The start page of the Infocenter contains a comprehensive list of documents named Version 5.0 for z/OS documentation.

2.4 The WebSphere family


The WebSphere Application Server is a cornerstone in the complete WebSphere suite, that makes up a comprehensive J2EE-compliant platform. The components of WebSphere can be grouped into three categories, illustrated by the WebSphere pyramid in Figure 2-12.

WebSphere Voice WebSphere Portal WebSphere Commerce WebSphere Everyplace

WebSphere MQ Workflow WebSphere BI Adapters ... ... WebSphere BI Message Broker

WebSphere Application Server

WebSphere Host Integration

WebSphere Studio Application Developer

Figure 2-12 The WebSphere pyramid

Foundation and tools


The core operating system of any e-business application must be a high-performance and extremely scalable transaction engine. This functionality is provided via the WebSphere Application Server. New applications are built in WebSphere Studio Application Developer (WSAD), and access to existing systems, however disparate they may be, is provided by WebSphere Host Integration and specialized tools in WSAD. These are the three capabilities that WebSphere's Foundation and Tools product families are designed to deliver.

Business portals
Products in this part of the pyramid are used to extend the customer experience. They consist of four product families: WebSphere Commerce Powerful sell-side solutions to handle the challenges encountered in customer and trading partner environments. It provides selling, buying and channel management solutions, from a simple online sales channel, to e-procurement, to a completely integrated, multi-tier demand chainall on a single, unified platform. WebSphere Portal

Chapter 2. Introduction to WebSphere for z/OS

47

A single point of personalized interaction with applications, content, processes, and people. WebSphere Everyplace Software for extending e-business applications to mobile devices everyplace software makes it possible to access data from a broad range of mobile devices. It delivers Web pages and e-business applications to the screens of cell phones and wireless PDAs. WebSphere Voice Software for enabling natural voice interactions with applications and data. Voice software uses speech as the user interface for data exchange. It is an extensive family that includes development tools and technologies transcription, voice response, message center services, access to business applications, and text translation between language.

Business integration
Business integration, which is the last side of the pyramid, is actually the heart of e-business. It is about integrating data, applications, processes, and people across and beyond the company, giving the power to make existing IT investment available to e-business. A vast set of products is available for integrating nearly everything with anything.

2.5 WAS 5.0.2 features and J2EE support


The current version of WebSphere Application Server is fully compliant with the J2EE 1.3 specifications. It even exceeds the specification with its extensions. The table below shows just some of the J2EE specifications that WebSphere Application Server supports.
Table 2-1 Some of the J2EE APIs supported by WAS 5.0.2 API EJB JDK Servlet API JSP JDBC WAS 5.0.2 2.0 1.3 (JDK 1.4 is required for WAS 5.1) 2.3 1.2 3.0

Further information can be found in the WebSphere Application Server Information Center at http://public.boulder.ibm.com/infocenter/wasinfo/index.jsp, or use the link in the Administrative Console.

The future is here


The next generation of WebSphere Application Server (Version 6) is coming soon. An early release for Windows, called WebSphere Application Server Technology for Developers, is ready for download from the WebSphere Application Server home page, accessible from the home page of the Administrative Console. Version 6 will be J2EE 1.4 compliant.

48

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 3.

WebSphere - DB2 environment


J2EE components deployed in a WebSphere Application Server often require access to data stored in databases (in DB2 tables). This access normally occurs through a logical entity, a Data Source. The use of Data Sources, compared to traditional direct driver access (via DriverManager) has many advantages, such as performance, security, and flexibility. In this chapter we discuss the process to configure those Data Sources, especially in the light of the availability of the IBM DB2 Universal Driver for SQLJ and JDBC.

Copyright IBM Corp. 2005. All rights reserved.

49

3.1 Introduction to the sample scenario setup


As part of the explanation of how to configure Data Sources based on the Universal Driver provider, we also put in place the setup for our application scenario. It is based on the following configuration, shown in Figure 3-1. Our setup uses two z/OS LPARS: WTSC54 with z/OS and WAS v5.02 with 2 application servers DBD8 accessed from WAS on WTSC54 via a type 2 driver DBD7 accessed from WAS on WTSC54 via a type 2 driver WTSC55 with z/OS and WAS v5.02 Accessing DBD8 on WTSC54 from WAS on WTSC55 via a type 4 driver Accessing DBD7 on WTSC54 from WAS on WTSC55 via a type 4 driver

WTSC55
DB2 tables

WTSC54

W AS V5
Application Server

T4

D D F

DBD7
Other DB2 address spaces

T2

Application Server

W AS V5
T4
D D F

DBD8 Other DB2 address spaces

T2

Application Server

z/OS
Figure 3-1 Configuration used in our sample scenario

DB2 tables

z/OS

Figure 3-1 shows an important aspect of the Driver type access. With local DB2 access using type 2 connectivity, only one DB2 subsystem can be accessed from within one application server. As a consequence, to have local access to DBD7 and DBD8 on WTSC54 it is required to have two servers, which is of course possible in a WebSphere Application Server Base Node (BN) and in a Network Deployment Node (ND) configuration. When connecting from the WAS running on WTSC55, we use type 4 connectivity to the DB2 for z/OS and OS/390 systems running on WTSC54. The type 4 driver that is used here is the z/OS Application Connectivity to DB2 for z/OS and OS/390 no-charge feature of DB2 for z/OS and OS/390 Version 7, and DB2 for z/OS Version 8. This driver is also known as the type 4 XA driver. For more information see 1.8.1, IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 on page 24. More details about the scenario can be found in Chapter 11, Sample application on page 245.

3.2 Introduction to DB2 drivers for Java


The JDBC standard defines four types of drivers. The drivers are responsible for physically accessing the DB2 databases. As this chapter is dedicated to WAS V5 on z/OS and the IBM

50

DB2 for z/OS and WebSphere: The Perfect Couple

DB2 Universal Driver for SQLJ and JDBC, we concentrate on the two driver types that are available from within a WAS that runs in a z/OS system, namely type 2 and type 4 connectivity. A description of all available driver types can be found in many documents, for example, in 1.7.2, JDBC driver types on page 21, and Chapter 3, Accessing DB2 from Java, in DB2 for z/OS and S/390: Ready for JAVA, SG24-6435. Three JDBC driver providers can be configured with WAS V5 on z/OS, after installation of PTF UQ85128 for WAS V5 to access DB2 for z/OS: DB2 for z/OS Local JDBC Provider (RRS) (a rename of the existing legacy driver) DB2 Universal JDBC Driver Provider DB2 Universal JDBC Driver Provider (XA) Table 3-1 provides an overview of the functionality supported by the different WAS V5.02 JDBC Driver Providers.
Table 3-1 Supported Driver Providers with WAS v5.02 on z/OS JDBC Driver type supported T2 support T4 support DB2 for z/OS Local JDBC Provider (RRS) YES NO DB2 Universal JDBC Driver Provider 2-phase commit with RRS 1PC to DB2 on z/OS To DB2 on other platforms not verified DB2 Universal JDBC Driver Provider XA Not on z/OS 2PC to DB2 on z/OS To DB2 on other platforms not verified

3.3 Data source definitions in WAS V5


From an application point of view, the Java code (JavaBean) looks at a DB2 resource via a Data Source object, which is logically addressable through a name, recommended to be in the form jdbc/data-name. This name, which is also known as the JNDI name, has been defined directly and/or as a reference in the Deployment Descriptor sections of the Enterprise Applications, and is known in the java:comp namespace for lookup. Some indirection is possible in the Deployment Descriptor reference section (where the name used in Java programs can be different from the real data source name). To access a DB2 resource, a program has to do a lookup of the JNDI name. This logical name has to be mapped to a real resource, a physical Data Source resource in WAS V5 that has been defined via the WebSphere admin console application. If required, this mapping can be changed during the deployment of the Enterprise Application. A WAS V5 system like a BaseNode (BN) configuration, or a Network Deployment (ND) configuration, is always composed of one or more application servers. Servers can be grouped in nodes, and nodes can be grouped in a cell. Definitions (such as the Data Source) can be made at each of these three levels. A Data Source definition done at cell level is available for all nodes; the definition at the node level is also available for all servers belonging to this node. However, keep in mind that only one local DB2 can be connected to a server, this because of a properties file that contains the local DB2 subsystem name, which goes with all local data source definitions. As a consequence, if you want servers connected to different local DB2s, you need to configure and run additional servers, and you have to make your Data Source definitions at the server scope level.

Chapter 3. WebSphere - DB2 environment

51

3.4 The IBM DB2 Universal Driver for SQLJ and JDBC
To access DB2 databases, a (new) JDBC Driver called the IBM DB2 Universal Driver for SQLJ and JDBC has been made available by IBM, both for z/OS and distributed platforms. To use the DB2 Universal Driver with WAS z/OS, the installation must have installed one of the following flavors of the driver: The DB2 for z/OS Version 8 DB2 Universal JDBC Driver. The driver is packaged as part of DB2 for z/OS V8. This version supports both type 2 and type 4 connectivity. The DB2 for z/OS Version 7 DB2 Universal JDBC Driver. This driver support is provided by APAR PQ80841 (and follow-on maintenance) on DB2 for z/OS and OS/390 V7. This version supports both driver types 2 and 4. Note: The DB2 Universal Driver Release 2.3.72 (available the PTF for APAR PQ93458) now officially supports type-4 XA connectivity to remote DB2 for Linux, UNIX, and Windows servers. However, accessing non-DB2 for z/OS databases from a WebSphere for z/OS V5.0 and V5.1 is not officially supported by WebShpere for z/OS. The standalone DB2 Universal JDBC Driver type 4 product (also known as z/OS Application Connectivity to DB2 for z/OS and OS/390). This version only supports type 4 connectivity to DB2 for z/OS databases. If this driver is installed, and you are using WebSphere for z/OS, then the DB2 Universal JDBC Driver Provider (XA) must be used on WAS z/OS to access remote DB2 for z/OS databases. (The use of the DB2 Universal JDBC Driver Provider using type 2 connectivity cannot be used since there is no local DB2 subsystem to connect to.) After the driver code (irrespective of which one of the aforementioned drivers you want to use) has been installed (into the HFS), you have to configure the Data Sources using the WAS Administrative Console application, or via the WebSphere administrative scripting program (wsadmin). Support in WAS for configuring Data Sources based on the new Universal Driver is added via PTF UQ85128 (APAR PQ80079). This maintenance should be applied to WAS V5 level W502002. This new support assumes that all driver specifics be available in the correct places within the HFS, and basically changes the admin console panels, so that Data Sources using the new drivers can be configured.

3.4.1 Summary of WAS z/OS external changes for the Universal Driver
The external changes that are made as a part of the WAS z/OS support for the new DB2 Universal Driver are summarized below: New environmental variables are provided to define the DB2 Universal JDBC Driver configuration to WAS z/OS. Two new JDBC Providers are provided to support the configuration of Data Sources that use the new DB2 Universal JDBC Driver. The DB2 390 Local JDBC Provider (RRS) option has been replaced by a new DB2 for z/OS Local JDBC Provider (RRS). New coexistence rules are defined regarding the coexistence of the legacy DB2 JDBC Driver, the DB2 Universal JDBC Driver, and Cloudscape. New setup is required for configuring the DB2 Universal JDBC Driver to WAS z/OS. The function of the DB2930LocalDataStorehelper and DB2390DataStoreHelper are consolidated into the DB2DataStoreHelper. The old helpers are retained for compatibility.

52

DB2 for z/OS and WebSphere: The Perfect Couple

Data Sources definitions, which are stored in the HFS system, have a hierarchical approach: JDBC provider The provider definition specifies the facilities (Java classes, code) that can be used by Data Sources under this provider. As indicated, two new providers have been added to support the Universal Driver, and the previous legacy provider has been renamed. Before we can define a data source, we first have to install the appropriate JDBC provider. Data Sources under the JDBC provider The Data Source, together with the Custom Properties linked to it, give more details about the physical database that backs the definition, and how it has to be accessed (remotely, locally). Some security elements can also be defined on this level.

3.5 Configuring Universal JDBC Driver type 2 connectivity


The type 2 driver is always a local driver. It only allows connections to a local DB2 (on the same LPAR) when running in a z/OS environment (or a DB2 Connect function that would be the gateway to a remote DB2 via DRDA, when using a DB2 for Linux, UNIX, and Windows client platforms). This is shown in Figure 3-2. The driver itself is composed of Java classes implementing the JDBC interfaces as defined in the core Java specifications. The classes are complemented by some native code (that is accessed through Java Native Interface(JNI)). This JNI code is distributed under the form of DLLs (shared objects (so) in z/OS) in the HFS. This .so file in the HFS could be a real file, or is for performance reasons often installed as a symbolic link to a member in a PDSE file.

SQLJ
SQLJ
SQLJ runtime
Common layer

JDBC

JDBC

SQLJ runtime
Common layer

T2 Native Libraries

T2 Native Libraries

T2
DB2 Connect

T2
D D F Other DB2 address spaces

DRDA

z/OS
DB2 tables
Figure 3-2 Type 2 drivers

Chapter 3. WebSphere - DB2 environment

53

The current (prior to the Universal Driver) type 2 driver (now called the Legacy JDBC driver), which replaced the older type 1 driver, has been around since WAS V4. This driver has been renamed to DB2 for zOS Local JDBC Provider (RRS). The configuration of this driver (and also the renamed one) for WAS V5 is explained in the document Using DB2 for z/OS in WebSphere for z/OS Version 5, TD101072, available from the Techdocs Web site at:
http://www-03.ibm.com/support/techdocs/atsmastr.nsf/WebIndex/TD101072

The Universal Driver also allows type 2 connectivity. This means that we have an additional flavor of the type 2 driver that can be configured. The Universal Driver allows the use of multiple driver types (type 2 and type 4 connectivity) with this driver code. In this section we describe how to configure type 2 connectivity using Universal Driver with WAS V5.

3.5.1 Specifying the Universal JDBC Driver provider


In our configuration we use the Universal Driver with type 2 connectivity on LPAR WTSC54 as depicted in Figure 3-1 on page 50. The JDBC provider that has to be used in WAS for this type of connectivity is the DB2 Universal JDBC Driver Provider. This provider is a non-XA JDBC provider. The DB2 Universal JDBC Driver is an architecture-neutral JDBC driver for distributed and local DB2 access. The driver supports Java Native Interface (JNI) based connectivity (that is, type 2 driver), which allows local access to DB2. In type 2 mode, all transaction processing under this provider is performed using two-phase commit processing under the control of RRS. RRS coordinates transactions using 2-phase or 1-phase commit processing. This provider not only supports the creation of WAS 5.0 Data Sources, but also 4.x level Data Sources. This provider allows applications to use both JDBC and SQLJ access to DB2 databases. We first have to connect to the Admin Console, as usual, using the following URL:
http://wtsc54.itso.ibm.com:9080/admin

On the screen that is returned (Figure 3-3), provide a user ID, and click OK.

Figure 3-3 Login screen

54

DB2 for z/OS and WebSphere: The Perfect Couple

On the general WAS V5 admin screen in the left frame, expand Resources, and select JDBC Providers (Figure 3-4).

Figure 3-4 Admin console after login

The JDBC provider panel is now displayed; see Figure 3-5.

Figure 3-5 Available JDBC providers

In order to have the possibility to attach to a particular DB2 subsystem per server (remember that we need to connect a V7 and a V8 DB2 system to the local WAS), we have to make the definitions in the server scope. Verify at this time that you work in the scope of one particular server; otherwise change the scope, and click Apply.

Chapter 3. WebSphere - DB2 environment

55

On the previous screen you saw a list of available JDBC providers; if the DB2 Universal JDBC Driver Provider is not among them, we have to add it. Click New. This will present a list of candidate JDBC providers, as shown in Figure 3-6.

Figure 3-6 List of available JDBC providers

In the drop-down list, select the DB2 Universal JDBC Driver Provider, and click Apply. This brings us to the General Properties window (Figure 3-7).

Figure 3-7 Driver properties

Have a look at the properties of this new provider. Notice that we have not yet defined the following symbolic variables. This will be done later (Figure 3-19 on page 65).
${DB2UNIVERSAL_JDBC_DRIVER_PATH} ${UNIVERSAL_JDBC_DRIVER_PATH} ${DB2UNIVERSAL_JDBC_DRIVER_NATIVEPATH}

56

DB2 for z/OS and WebSphere: The Perfect Couple

In the right columns of the display a contextual explanation is given for all properties. Click Apply again. The new JDBC provider is now defined for this server, but the definition is not saved yet. It is good practice to save the changes at this time (by clicking the Save button). After the save, we return to the JDBC Provider list in which the new provider should be present now (Figure 3-8).

Figure 3-8 JDBC new provider list

3.5.2 Defining Data Sources under this provider


Now that the new driver is available from the JDBC provider list, select the DB2 Universal JDBC Driver Provider by clicking on the link (in blue). On the bottom of the next window, under the provider characteristics, a frame called Additional Properties (Figure 3-9) is presented. Within this frame we can define Data Sources (V5 and V4).

Figure 3-9 Additional properties of the DB2 Universal JDBC Driver Provider

As we want to define a WAS V5 Data Source, select Data Sources. This takes us to the window shown in Figure 3-10 on page 58.

Chapter 3. WebSphere - DB2 environment

57

Figure 3-10 New Data Source

No Data Source has been defined at this point. Click New for a new Data Source. In the next windows, Figure 3-11, Figure 3-12 on page 59, and Figure 3-13 on page 60, we define the properties of the (new) Data Source. In the right column contextual information is provided about the meaning of each of the properties.

Figure 3-11 General Properties 1

Some properties are marked as mandatory (with a red asterisk). We provide information for the following fields: Name (display) This is a label; specify a name that is as meaningful as possible.

58

DB2 for z/OS and WebSphere: The Perfect Couple

JNDIName

By convention this should start with jdbc/; we should use a name that expresses as close as possible the addressed DB2 and driver type. jdbc/T2DBD8 (DBD8 on Local via type2) The JNDIName will have to be set in the Deployment Descriptors of the Web Applications and EJBs, or if the name defined in the descriptors is not a defined JNDI name of a Data Source, it will have to be overridden in the deployment dialog.

Container managed persistence

Check this box if CMP EJBs will make use of this Data Source.

Figure 3-12 General Properties 2

Statement Cache Size

This parameter influences the performance of JDBC. SQLJ has been prepared in advance. JDBC statements that are used repetitively are prepared the first time and can been cached afterwards in prepared state. This is the user ID/password that will be used to access DB2 with component managed security. The alias has to be defined beforehand. This is the user ID/password that will be used to access DB2 with container managed security. The alias has to be defined beforehand.

Component-managed Authentication Alias

Container-managed Authentication Alias

Chapter 3. WebSphere - DB2 environment

59

Figure 3-13 General Properties 3

Other general properties are displayed. When all properties have been filled in or accepted click Apply.

JAAS alias
Java Authentication and Authorization Services (JAAS) is a Java API to establish an authenticated user ID. This API can be invoked in several instances, in particular when connecting to DB2. This connection can be established on behalf of two environments: Container (using the user ID of the thread that is executing) Component/application (the user ID is explicitly passed on the getConnection call) The selection between the two options is made in the Deployment Descriptor (EJB, Web application) with the "res-auth" option. A JAASAlias (userID/password) can be specified using the Administrative Console application via Security JAAS Configuration J2C Authentication Data. For each of the two options, JAAS aliases are defined beforehand (see above), and then set for a particular DataSource. The option to define a JAASAlias is available on the data source definition panel by JDBC Providers JDBC-provider-name Data Sources datasource-name, in the Component-managed or Container-managed Authentication Alias field. Several JAASAliases can be defined and one of those can then be set as a JAASAlias reference for application or component. More information can be found in WebSphere datasource settings for authentication on page 134 (for a WAS environment), and Setting up JAAS security entries on page 163 (for a WSAD environment). The Data Source is now available, and it is now time to save our changes. After this, return to the JDBC Provider/Data Source for additional definitions. The new Data Source has a logical name (JNDI name), but is not yet connected to any real DB2 subsystem. Under the General Properties of the Data Source, a selection Additional Properties is shown (Figure 3-14 on page 61).

60

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-14 Additional Properties

Select Custom Properties. The next window (Figure 3-15, Figure 3-16 on page 62, Figure 3-17 on page 63, and Figure 3-18 on page 64) shows many properties. We first define whether this Data Source is accessed via type 2 or type 4 connectivity, and what DB2 subsystem the Data Source is linked to. Properties have to be changed accordingly. All have contextual explanations in the Description column. It is also indicated whether the property is required (true) or not (false). When you want to change a property, click the property name and change the value. After each change, click OK, and at the end, Save all values in the WAS configuration.

Figure 3-15 Custom Properties 1

Chapter 3. WebSphere - DB2 environment

61

The values are: databaseName This is the location name of the DB2 system you want to connect to (DBD8 in our case. Note that on our systems, the DB2 subsystem name is the same as the DB2 location name. That is not necessarily the case in your installation.) This is a definition for a type 2 Data Source, so we specify 2.

driverType

Figure 3-16 Custom Properties 2

traceLevel

The DB2 trace level for logging to the logWriter or trace file. At this point we do not require any tracing so we specify 0. Without any code change required, this setting controls whether LOB locators are used to fetch LOB data. For now, we use the default setting true.

fullyMaterializeLobData

62

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-17 Custom Properties 3

More information about the following parameters can be found in 5.6, Special registers on page 121. currentPackageSet Specifies the content of the CURRENT PACKAGESET special register. The CURRENT PACKAGESET special register is used as a collection name, when searching for an appropriate package to execute. Identifies the default schema name used to qualify unqualified database object references. Identifies the name of the qualifier (schema) name when using a shadow catalog for retrieving metadata information about DB2 objects stored in the DB2 catalog.

currentSchema cliSchema

Chapter 3. WebSphere - DB2 environment

63

Figure 3-18 Custom Properties 4

preTestSQLString

Specify a dummy select from an existing table. This statement is used for the pre-test connection function, for example, SELECT 1 FROM SYSIBM.SYSDUMMY1. Initializes the CURRENT SQLID special register with the value specified here. We specify ITSOUSER. This value specifies the default schema name that is used to qualify unqualified database objects in dynamically prepared SQLstatements if currentSchema is not used.

currentSQLID

This concludes the definition of a Data Source using type 2 connectivity with the DB2 Universal Driver. However, we still have to set the values for the symbolic variables that were used when defining the JDBC provider before.

3.5.3 Setting/verifying the symbolic environment variables


To specify environment variable, on the main Admin Console display, in the left frame, select Environment Manage WebSphere Variables (Figure 3-19 on page 65). This shows the available WebSphere (environment) variables that are already defined. Determine whether we need to do this on the server scope, or maybe we can do on an higher scope. Change the scope accordingly. (We use the Server scope, as it gives us more flexibility, as we need to be able to connect to a V7 and V8 DB2 for z/OS system.)

64

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-19 WebSphere Variables

We must set values for the following symbolic variables: ${DB2UNIVERSAL_JDBC_DRIVER_PATH} /usr/lpp/db2810/jcc/classes ${UNIVERSAL_JDBC_DRIVER_PATH} /usr/lpp/db2810/jcc/classes ${DB2UNIVERSAL_JDBC_DRIVER_NATIVEPATH} /usr/lpp/db2810/jcc/lib This can easily be done with the New selection if they do not exist yet, or by a change otherwise. Each time, enter the variable name, value, and optionally a description. Repeat it, and if required correct it. Afterwards, the list of variables should look like Figure 3-20.

Figure 3-20 Symbolic parameters

3.5.4 Defining DB2 Universal Driver - General properties


We are still not done for the type 2 driver. An additional properties file, located in the HFS, has to be created and referenced. The most imported information in this file, that only exists for type 2 connectivity, is the subsystem ID of the local DB2. We have to create a DB2 Universal Driver general properties file for use by DB2 Universal JDBC Driver using type 2 connectivity under WAS z/OS. This run-time properties file is used 65

Chapter 3. WebSphere - DB2 environment

for specifying various run-time options that the DB2 Universal JDBC Driver uses for type 2 connectivity. These options are specified as properties in the form of parameter=value. Refer to Customizing the DB2 Universal JDBC Driver global properties file in DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414, or the README file packaged with the DB2 Universal JDBC Driver for a detailed description of each of the properties that can be specified. This file is not required, but if not provided, the Universal Driver runs using default processing. There are different ways to specify a DB2 Universal Driver general properties file; however, when running in a WebSphere Application Server environment, the recommended way to specify the properties file is as a JVM system property. In that case, the fully qualified HFS file name must be provided as input to the Universal Driver. You can specify a JVM system property as follows:
db2.jcc.propertiesFile = <fully-qualified-hfs-filename>

Since such driver general properties are typically specific to a driver load (that is, server) versus to all servers using the JDBC provider, it is best that this jvm property be set at the server level. We use the following properties file (Example 3-1) when connecting to DBD8.
Example 3-1 Properties file for SSID DBD8 db2.jcc.ssid=DBD8 db2.jcc.override.traceFile=/u/rc54/cel541nd541sc54ws541sc54/tracejava

Of specific interest is the db2.jcc.ssid property. This property can be set to specify the DB2 subsystem identifier (not the DB2 location name) to be used by the DB2 Universal JDBC Driver type 2 processing as the local subsystem name the driver should connect to. If this property is not provided, then the driver will use the subsystem identifier it finds in the DSNHDECP load module. DSNHDECP is loaded using the search sequence specified in the STEPLIB environment variable, or the //STEPLIB DD name concatenation. If that DSNHDECP load module does not accurately reflect the desired subsystem, or multiple subsystems may be using a generic DSNHDECP, then this property must be specified. Also noteworthy is the following trace property supported by the Universal Driver:
db2.jcc.override.traceFile = <fully-qualified-hfs-filename>

This property enables driver global java-side tracing inside the driver. You can reference the properties file in the following way: Connect to the Admin Console as usual, select Servers Application Servers, and click the server where you want to add the jvm property (Figure 3-21 on page 67).

66

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-21 Application Server selection

From the Server page that was selected, go to Process Definition Servant (Figure 3-22).

Figure 3-22 Servant selection

On the Servant page, go down to Additional Properties at the bottom of the page. Click Java Virtual Machine (Figure 3-23).

Figure 3-23 Additional properties under Process Definition/Servant

On the Java Virtual Machine page, again go down to Additional Properties at the bottom of the page. Click Custom Properties (Figure 3-24 on page 68).

Chapter 3. WebSphere - DB2 environment

67

Figure 3-24 Custom Properties under Servant/Java Virtual Machine

On the Custom Properties page, click New to configure a new JVM property under the server. The name of the property should be db2.jcc.propertiesFile, as shown in Figure 3-25.

Figure 3-25 New property

The value of the property should be the fully qualified HFS file name that you have created and populated with the DB2 Universal JDBC Driver properties that you want the type 2 driver to use under the selected server (with information like in Example 3-1 on page 66). Once you have done this, click OK and save the configuration. This is a specification for the JVM of the servants of a particular Application Server. Therefore, we cannot have a second one referencing another local DB2.

3.5.5 Searching for the package to execute


When using type 2 connectivity you have a number of options to indicate to DB2 where to search for the package that needs to be executed. These options fall into two categories: Specification as a driver property Specification as a Data Source property

Package search via a driver configuration property


DB2 Universal Driver configuration properties allow you to set property values that have driver-wide scope. Those settings apply across applications and Data Source instances. You can change the settings without having to change application source code or Data Source characteristics.

68

DB2 for z/OS and WebSphere: The Perfect Couple

Again there are two options. They are mutually exclusive: db2.jcc.planName Specifies the DB2 plan name that is used by the RRS attach to create the thread when a JDBC or SQLJ connection to a data source is established; for example: db2.jcc.planName=MYSQLJPL When you bind that plan you can include the collections that you want DB2 to search for packages using the PKLIST keyword; for example: BIND PLAN(MYSQLJPL) PKLIST(TESTCOLL.*, PRODCOLL.*) This is the same as you would normally do with static COBOL programs. You can override db2.jcc.planName by setting the planName property for a Connection or DataSource object. Specifies a list of collections that is used to search for a package when a JDBC or SQLJ connection to a data source is established. You can use this property if you do not bind plans for your SQLJ programs or for the JDBC driver. The format of the package list is: db2.jcc.pkList=TESTCOLL.*,PRODCOLL.* You can override db2.jcc.pkList by setting the pkList property for a Connection or DataSource object. *

db2.jcc.pkList

If you do not specify the db2.jcc.planName property or the db2.jcc.pkList property. The DB2 Universal JDBC Driver uses the db2.jcc.pkList default value of NULLID.*, unless you specify currentPackageSet or current PackagePath (custom) property on the DataSource or Connection object. Note: When the db2.jcc.planName option is used, the user ID associated with the WebSphere address space needs to be authorized to execute the plan. DB2 checks EXECUTE ON PLAN authority when RRS creates the thread. This is before the driver can switch to the user ID that is used on the getConnection() call.

Package search via a DataSource or Connection property


As mentioned above, you can also use the currentPackageSet or current PackagePath (custom) property on the DataSource or Connection object to indicate to DB2 where (in which collections) you want DB2 to search for a package. currentPackageSet Specifies a single collection ID to search for DB2 packages by the DB2 Universal Driver. (When used by a connection that is using type 4 connectivity, the default is NULLID. For type 2 connectivity, if a value for currentPackageSet is not specified, the property value is not set.)

currentPackagePath Specifies a list of collections on the server. The DB2 server searches these collections for the DB2 packages for the DB2 Universal JDBC Driver. currentPackagePath and currentPackageSet are used in the same way as the DB2 CURRENT PACKAGESET and CURRENT PACKAGE PATH special registers, but can be set inside or outside (at the DataSource) of the application. The precedence rules for the currentPackagePath and currentPackageSet properties follow the precedence rules for the DB2 CURRENT PACKAGESET and CURRENT PACKAGE PATH special registers. You can also use the planName and pkList properties at the DataSource and Connection object level in a similar way as you use db2.jcc.planName and db2.jcc.pkList driver configuration properties.

Chapter 3. WebSphere - DB2 environment

69

3.5.6 Linking to the DB2 libraries


The application server also requires access to three DB2 libraries: DB2xx.SDSNEXIT DB2xx.SDSNLOAD DB2xx.SDSNLOD2 Allowing DB2 to access these libraries can be done in several ways: The libraries can be placed in the LINKLIST of the z/OS operating system. The libraries are added to the JCL of the startup procedure of the Application Server Servant. This can easily be done with a JCL INCLUDE statement from the main start procedure. In the procedure shown in Example 3-2, which is the start procedure for an Application Server Servant, besides the ENV parameter, a parameter named Z is used. It points to an include member, shown in Example 3-3.
Example 3-2 Start procedure for Servant //WS5541S PROC ENV=CL541.ND541.WS541,Z=WS5541SZ // SET ROOT='/WebSphereBS/V5R0M0/BS01' //BBOSR EXEC PGM=BBOSR,REGION=0M,TIME=NOLIMIT, // PARM='TRAP(ON,NOSPIE),ENVAR("_EDC_UMASK_DFLT=007") /' //BBOENV DD PATH='&ROOT/&ENV/was.env' // INCLUDE MEMBER=&Z

In the included member, the DB2 libraries have to be added.


Example 3-3 included member with updated STEPLIB for DB2 V8 //* //* Output //* //CEEDUMP //SYSOUT //SYSPRINT //* //*Steplib //* //STEPLIB // // // // // DDs DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE Setup DD DD DD DD DD DISP=SHR,DSN=BBO5S54.SBBOLD2 DISP=SHR,DSN=BBO5S54.SBBOLOAD DISP=SHR,DSN=DB2D8.SDSNEXIT DISP=SHR,DSN=DB2D8.SDSNLOAD DISP=SHR,DSN=DB2D8.SDSNLOD2

The value of the Z parameter, which in the example has a default, can be overridden also via the Administrative Console application to point to another include member. To do this, go to Application Servers Servername Process Definition Servant and change, as appropriate, the property value of startCommandArgs (Figure 3-26 on page 71).

70

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-26 Start command and arguments for Servant

Note: In a Base Node (BN) configuration, WAS V5 application servers cannot be started and stopped via the Administrative Console. The required libraries can also be specified by using the Export function of Unix System Services. This has to be done via the Custom Property settings of the Servant. Go to Servers Application Servers Server-name Process Definition Servant. In the this panel, select Environment Entries at the bottom (Figure 3-27).

Figure 3-27 Environment entries

A new environment variable has to added, or changed if already existing (Figure 3-28 on page 72).

Chapter 3. WebSphere - DB2 environment

71

Figure 3-28 New environment entry

Fill in the name and the value for the new variable (Figure 3-29); in our case:
STEPLIB=$STEPLIB:DB2xx.SDSNEXIT:DB2xx.SDSNLOAD:DB2xx.SDSNLOD2

Note: The header of the panel is Custom Properties, whereas in fact you are defining environment variables, so do not let the heading mislead you.

Figure 3-29 Adding the STEPLIB variable

Save the configuration, and we are done. Attention: The previous approach for adding the DB2 libraries to an Application Server has not been verified. We experienced time outs in the Admin Console application after the above changes had been made. This concludes the definition of the type 2 driver for DBD8. Note again that we can only associate one DB2 system when using type 2 connectivity per Application Server. This is because we have to specify the JVM System property db2.jcc.propertiesFile, by which we have to point to the properties file that will be used by the 72
DB2 for z/OS and WebSphere: The Perfect Couple

Universal Driver. The scope for the definition of this variable is a (JVM) property of an Application Server. If you need the ability to connect to another local DB2 using a type 2 connectivity, you have to define it in a second Application Server (or use a DRDA connection even though the DB2 system is local to the Application Server). Nevertheless, it can be useful to define other data sources using type 2 connectivity for the same DB2 subsystem. In the Custom Properties section, you can specify properties that could be specific for specific applications or Beans. For example, they can be using different CurrentSQLID, currentPackageSet, or trace parameters.

3.5.7 Creating a new Application Server


To be able to use a type 2 connection to the DB2 V7 system (DBD7), we define a second Application Server. After logon to the Administrative Console, select Application Servers in the left frame, and retrieve an overview of the existing Application Servers (in our Base Node configuration) in the right frame, as shown in Figure 3-30. Click New to define a second server.

Figure 3-30 Select Application Servers

The following window that is presented is the Create New Application Server window, as shown in Figure 3-31 on page 74.

Chapter 3. WebSphere - DB2 environment

73

Figure 3-31 Create a new server

Enter the following information: Server name: wsc54asc54 Select template: Existing application server Click Next. This takes you to the window shown in Figure 3-32.

Figure 3-32 Create new Application Server

Click Finish. This takes us to the window in Figure 3-33 on page 75 with an overview of the Application Servers including the new server, and an invitation to save to the master configuration.

74

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-33 Overview with new Application Server

Click Save to save the configuration. Let us now have a look at the HFS file system, where the actual configuration resides. The mount point for our WAS V5 is WebSphereBS/V5R0M0/BS01. From here we find two branches (subdirectories): Daemon AppServer Under AppServer, we find the Cell/Node/Server hierarchy configuration. As shown in Figure 3-34 on page 76, we have two servers, and each server has a was.env file, which is directly addressed via a symbolic link from the mount point. The server subdirectory is fine, but the name of the symbolic link, CL541.ND511.BBOS001, was generated by the Admin Console application. We will now change this.

Chapter 3. WebSphere - DB2 environment

75

/<mount point>
Syml CL541.CL541.WS541D Syml CL541.ND541.BBOS001 Syml CL541.ND541.WS541

+--/Daemon +--/AppServer +--/config +--/cells +--/cel541 +--cell.xml +--/applications +--/clusters +--/nodes +--/nd54 +--node.xml +--serverindex.xml +--/servers +--/ws541sc54 +--was.env +--/ws541sc54a +--was.env
Figure 3-34 Configuration hierarchy

Daemon
CR

Base Node
CR

Server
Servant

Server

Cell

CR

Servant

In the Admin Console, return to the overview panel of the Application Servers and select the new server (Figure 3-35).

Figure 3-35 Overview of Application Servers

After selecting the server, the window shown in Figure 3-36 on page 77 appears. It shows the properties of the new server, including the short name that we want to change.

76

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-36 Configuration of new server

Override the short name, for example, WS541A (in capitals). Click OK and save the configuration. This will create a new symbolic link CL541.ND541.WS541A in Figure 3-34 on page 76 for the new server that can be used in the start command of the server. The new Application Server is defined, but what about the start command? The start command for the first application server looks like:
START WS5541C,JOBNAME=WS541,ENV=CL541.ND541.WS541

For the second it could be:


START WS5541C,JOBNAME=WS541A,ENV=CL541.ND541.WS541A

In both cases, the ENV parameter represents the symbolic link to the was.env file of the server. In both cases we use the same start JCL procedure. However, since the second server will have to point to DBD7 (our DB2 V7 subsystem), we have to include the //STEPLIB DD statements that reference to the DB2 V7 libraries. Remember from Example 3-2 on page 70 that the procedure can point to an include member via the Z parameter, like Example 3-3 on page 70, in which we added the DB2 V8 libraries. We have to create a new member (Example 3-4), and reference it via the Z parameter at startup:
START WS5541C,JOBNAME=WS541A,ENV=CL541.ND541.WS541A,Z=WSD7SZ

This is the way it has to be done in a Base Node configuration. In a Network Deployment node, servers can be started by the Admin Console, but the new Z parameter also has to be added to the Process Definition Servant startCommandArgs field of the new server, like in Figure 3-26 on page 71.
Example 3-4 Include member WSD7SZ with STEPLIB for DB2 V7 //* //* Output DDs //* //CEEDUMP DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE Chapter 3. WebSphere - DB2 environment

77

//SYSOUT //SYSPRINT //* //*Steplib //* //STEPLIB // // // // //

DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE DD SYSOUT=*,SPIN=UNALLOC,FREE=CLOSE Setup DD DD DD DD DD DISP=SHR,DSN=BBO5S54.SBBOLD2 DISP=SHR,DSN=BBO5S54.SBBOLOAD DISP=SHR,DSN=DB2D7.SDSNEXIT DISP=SHR,DSN=DB2D7.SDSNLOAD DISP=SHR,DSN=DB2D7.SDSNLOD2

The new server does not have its own admin console application. All definitions, JDBC providers, and data sources are always done via this prime server. We also create a data source (for type 2 connectivity) for the second Application Server ws541asc54 with JNDIname:
jdbc/T2DBD7 (DBD7 on Local via type2)

To do so, we can use the procedure outlined in Defining Data Sources under this provider on page 57. Attention: If we need access to two or more DB2 subsystems from within the same Application Server, we have to use a mixture of T2 and T4 data sources.

3.6 Configuring Universal JDBC Driver type 4 connectivity


The type 4 driver is always some kind of a remote driver. It allows us to connect to a local DB2 (on the same LPAR) or a remote DB2, but always over TCP/IP. The driver is a pure Java driver, and therefore only composed of Java classes implementing the JDBC interfaces as defined in the JDBC core specification. This makes it possible to use this driver in many environments, including a browser with Applets; only a Java Virtual Machine is required. This is also depicted in Figure 3-37 on page 79.

78

DB2 for z/OS and WebSphere: The Perfect Couple

SQLJ
SQLJ runtime

JDBC

SQLJ
SQLJ runtime

JDBC

Common layer

Java Classes

T4 (only to z/OS)

Common layer

z/OS
DRDA DRDA

T4

Java Classes

T2
D D F Other DB2 addres spaces

SQLJ
SQLJ runtime

JDBC

Common layer

Java Classes

DRDA

T4

z/OS
DB2 tables

Distributed platform

Figure 3-37 type 4 driver

The type 4 driver for z/OS is delivered with DB2 Version 8 and available also for DB2 V7 via the maintenance stream. WAS PTF UQ85128 allows WAS V5 to specify the DB2 Universal Driver when configuring a data source. It comes in two flavors: DB2 Universal JDBC Driver Provider (non-XA) One-phase commit to DB2 on z/OS DB2 Universal JDBC Driver Provider (XA) Two-phase commit to DB2 on z/OS

3.6.1 Using the Universal Driver for type 4 (non-XA)


The JDBC provider that has to be used for this type is DB2 Universal JDBC Driver Provider. This provider is a non-XA JDBC provider. The DB2 Universal JDBC Driver is an architecture-neutral JDBC driver for distributed and local DB2 access. The Universal JDBC Driver supports Java communication-based connectivity (that is, type 4 connectivity), which allows distributed access to DB2. Under WAS z/OS, type 4 driver access to DB2 is only supported for connectivity to z/OS DB2 databases on the z/OS platform. Functionally, type 4 connectivity may work to connect to DB2 databases on other platforms, but this function has not been functionally verified under WAS z/OS V5.0 and V5.1, and is therefore not supported. All transaction processing under this provider, using type 4 connectivity, is performed using

one-phase commit processing.


This provider not only supports the creation of WAS 5.0 data sources, but also 4.x level data sources. This provider allows applications to use both JDBC and embedded Structured Query Language in Java (SQLJ) access to DB2 databases.
Chapter 3. WebSphere - DB2 environment

79

To use this provider, you must have the DB2 Universal Driver for SQLJ and JDBC for DB2 Version 7 or DB2 Version 8 installed and configured to WAS z/OS (as discussed in 1.9, Using the DB2 Universal Driver for SQLJ and JDBC on page 26). Tip: This driver with single phase commit (1PC) capabilities may be used when DB2 is the only resource manager involved in a transactional unit of work.

Defining Data Sources under this provider


Most of the steps for defining a type 4 connection are the same as when defining type 2 connectivity using the Universal Driver, except when it comes to the Custom Properties of the Data Source. In this window, the properties will be different. In most situations, this version of type 4 driver support is not very interesting, as it only offers 1PC support. Most real-life situations require 2-phase commit. For those, we will use the XA flavor of the JDBC provider, which is described hereafter.

3.6.2 Using the Universal Driver for type 4 (XA) connectivity


This provider is a XA JDBC provider. The DB2 Universal JDBC Driver is an architecture-neutral JDBC Driver for distributed and local DB2 access. The Universal Driver supports Java communication-based connectivity (that is, driver type 4), which allows distributed access to DB2. Under WAS z/OS, type 4 connectivity is only supported for connectivity to DB2 for z/OS databases on the z/OS platform. Functionally, type 4 connectivity may work to connect to DB2 databases on other platforms, but this function has not been functionally verified under WAS z/OS V5.0 and V5.1, and is therefore not supported. The J2EE JTA/XA transaction support is provided by the Universal Driver using type 4 connectivity. The J2EE JTA/XA transaction architecture is supported by the Universal Driver under this JDBC provider. This permits the coordination of global transactions across multiple resource managers using 2-phase commit processing. The driver also supports one-phase transaction processing under this provider. Type 2 connectivity is not supported by this provider and therefore should not be used when defining a data source under this provider. Although the Universal Driver using type 2 connectivity does not support JTA/XA transactions as such, it does of course support 2-phase commit. When using type 2 connectivity, an RRS-based interface is used to perform 2-phase commit using z/OS native functionality. This provider only supports the creation of WAS 5.0 data sources. The creation of 4.x level data sources is not supported. This provider allows applications to use both JDBC and SQLJ access to DB2 databases. To use this provider under WAS z/OS, you must have the IBM DB2 Universal Driver for SQLJ and JDBC for DB2 for z/OS and OS/390 Version 7, or DB2 for z/OS Version 8 installed and configured to WAS z/OS, or you must have the z/OS Application Connectivity to DB2 for z/OS and OS/390 product installed and configured. It provides a standalone type 4 XA Universal Driver. (See 1.8.1, IBM z/OS Application Connectivity to DB2 for z/OS and OS/390 on page 24, for more details.)

Defining the DB2 Universal JDBC Driver Provider (XA)


Referring to Figure 3-1 on page 50, we will configure two Data Sources on WTSC55, using this JDBC provider, one to each of the DB2 systems (DBD7 and DBD8) on WTSC54.

80

DB2 for z/OS and WebSphere: The Perfect Couple

Most of the steps for defining type 4 XA connectivity are the same as for type 2 connectivity, except that you do them under another JDBC provider. This provider for T4 XA connectivity first has to be added to our provider list. As we only have one Application Server on WTSC55, and the data sources we will add are using type 4 connectivity, we can make the definitions at the Node scope, or even at the Cell scope level. As we did for the type 2 connectivity before, we verify the presence of the Universal JDBC driver for XA. If not, we add it. To add a new JDBC provider, log into the Admin Console, and select Resources JDBC Providers New. Then select DB2 Universal JDBC Driver Provider (XA) in the drop-down list, as shown in Figure 3-38. If that option is not there, it is very likely that WAS z/OS is not at the 502002 level. (Support in WAS z/OS for configuring Data Sources based on the new Universal Driver is added via PTF UQ85128 (APAR PQ80079)).

Figure 3-38 Create new JDBC provider

If you see the DB2 Universal JDBC Driver Provider (XA) in the list of JDBC providers overview (Figure 3-39 on page 82), the provider is OK.

Chapter 3. WebSphere - DB2 environment

81

Figure 3-39 JDBC Providers

Now we need to check the properties (and the symbolic variables they use) for this provider. Selecting the DB2 Universal JDBC Driver Provider (XA) provider takes us to a window with configuration properties, as in Figure 3-40 on page 83. The information provided by the Admin Console application for the CLASSPATH and Implementation Classname should be OK.

82

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-40 Configuration for XA JDBC provider

Also notice the symbolic variables. They must be specified, as before, using the Admin Console, via Environment Manage WebSphere Variables (Figure 3-41 on page 84). The following variable needs to be defined: DB2UNIVERSAL_JDBC_DRIVER_PATH, pointing to /usr/lpp/jcct4/classes This is where the type 4 XA driver Java classes are installed on WTSC55. There is no need for other variables like DB2UNIVERSAL_JDBC_DRIVER_NATIVEPATH; as the T4 driver is a pure Java driver, there is not need for a native library. This also means that it is not required to change the WAS V5 JCL startup procedures to add the DB2 libraries to them.

Chapter 3. WebSphere - DB2 environment

83

Figure 3-41 Manage WebSphere Variables

Defining Data Sources under this provider


Now we can define Data Sources under the Universal JDBC Driver Provider (XA). To do so, return to the JDBC Provider window (Resources JDBC Providers Universal JDBC Driver Provider (XA)). At the bottom of the window, click Data Source (see Figure 3-42).

Figure 3-42 DB2 Universal JDBC Driver (XA)

On the new panel that shows up, click New to define a data source. This takes you to a window where you can define the basic properties for the Data Source to be defined. This is shown in Figure 3-43 on page 85.

84

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 3-43 New Data Source type 4 definition to DBD8

In the general properties section we give adequate names for the mandatory properties. We used names that express as closely as possible the DB2 we want to address, as well as the type of connection we want to use. Name JNDIname ITSOT4DBD8 jdbc/WTSC54T4DBD8 (connecting to DBD8 on WTSC54 via a type 4 connection) Since CMP EJBs will make use of this Data Source, we check the box.

Container managed persistence

The JNDIname will have to be set in the Deployment Descriptors of the WebApps and EJBs; or if the name defined in the descriptors is not a defined JNDIname of a Data Source, it will have to be overridden during the Deployment dialog. Click OK. You can now see the Data Source that you just defined. Select the Data source, and go to the bottom of the next window that is presented to you. Below the General Properties, you find the Additional Properties section (Figure 3-44 on page 86). Select Custom Properties.

Chapter 3. WebSphere - DB2 environment

85

Figure 3-44 Custom Properties selection for the Data Source

The properties in the Custom Properties panel that need to be specified are slightly different (from the type 2 driver), as this is the definition of a Data Source that is using a type 4 connection. Figure 3-45 and Figure 3-46 on page 87 show the main properties for type 4 connectivity that are different from a type 2 connection.

Figure 3-45 Properties for a type 4 Data Source different from type 2

They are: databaseName The location name of the DB2 you want to connect to.

86

DB2 for z/OS and WebSphere: The Perfect Couple

driverType

To indicate that this is the definition for a Data Source with type 4 connectivity. (Note that in our systems the DB2 subsystem name is the same as the DB2 location name. This is not necessarily the case in your installation.) IP address or host name.

serverName

Figure 3-46 Properties for a type 4 Data Source different from type 2

portnumber

This is the port number that the DB2 system that we want to connect to is listening on. It can be obtained by using the -DIS DDF command. The DB2 trace level for logging to the logWriter or trace file. It would normally be set to 0 (zero). The trace file that will be used when the trace is active. Without any code change required, this setting controls whether LOB locators are used to fetch LOB data.

traceLevel

traceFile fullyMaterializeLobData

After this the configuration should be saved. The Data Source definition has to be repeated for each remote DB2 we want to connect to. We also need connectivity to our V7 DB2 system, so we create a Data Source pointing to DBD7. The JNDIname would be: jdbc/WTSC54T4DBD7 (DBD7on WTSC54 via type 4 connectivity) After saving the configuration, this concludes the installation of the Data Sources that we need for type 4 connectivity.

Chapter 3. WebSphere - DB2 environment

87

3.7 Summary
A WAS V5 system on z/OS can now be configured with three JDBC Drivers for DB2 access, offering T4 and T2 support. Currently only T4 to another DB2 on z/OS is supported from within WebSphere. The new Universal Driver gives 2-phase commit (2 PC) support for both type 2 and type 4 connectivity. This allows the creation of a Global Unit of Work (GUOW) under WAS V5, which can include, besides access to transactional systems like IMS and CICS, access to a local DB2 and/or to remote DB2 systems. The legacy DB2 JDBC driver, now renamed to DB2 for z/OS Local JDBC Provider (RRS) in the Administrative Console dialog panels, and although still available at this time, will probably be phased out in the future. Customers are strongly encouraged to use, or convert to using, the IBM DB2 Universal Driver for SQLJ and JDBC.

88

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 4.

DB2 and Java architecture guide


This chapter discusses application architecture considerations within a J2EE environment that affect data access. We will not dive into specific details on how to implement all the referenced technologies. Instead, this chapter describes each of the technologies for architectural considerations and provides general guidelines for database access from each of the Java-related technologies. The chapter contains the following topics: Introduction to J2EE data access architecture Servlets and JavaServer Pages Enterprise JavaBeans Bean paradigms together Stored procedure usage Java Data Objects

Copyright IBM Corp. 2005. All rights reserved.

89

4.1 Introduction to J2EE data access architecture


For most applications, data access is the last tier and the endpoint of an application. Good designs generally provide separate application layers for presentation (or user interface); business processing or logic; and then finally a data access layer that retrieves, stores, or massages data within the relational database. The separation of these functions into separate components should be a requirement for any application architecture. History tells us that application requirements, implementation technologies, and pretty much everything else will change. Without separating applications into components, the work required to update, maintain, and troubleshoot grows exponentially with the complexity of todays enterprise applications. This chapter makes the assumption that you have chosen to implement a Java-based application and will be accessing data that resides on DB2 UDB for z/OS. Each of the Java technologies are described and considered for use as the data access portion. For components that should not access data directly, we attempt to position their usage within a larger architecture. As in all decisions, attempting to decide which technology to exploit is ultimately an exercise in weighing trade-offsperformance and scalability versus ease of development, operations, and maintenance.

4.2 Servlets and JavaServer Pages


Servlets were one of the first server-based execution environment implementations for the Java programming language. Widely implemented and platform independent, servlets are Java programs that are executed at the server instead of at a local client such as within an applet or application. Servlets are Java code that has access to the full family of Java APIs, but their primary goal is to handle requests and generate responses. Servlets are almost exclusively invoked by HTTP requests. Once an HTTP request for a servlet causes a Web server to invoke the servlet, the servlet executes some set of functions, and ultimately generates a dynamic HTML response, which is sent back to the client for rendering. The client is usually a Web browser. In implementation, the servlet execution environment provides excellent performance when compared to other request response mechanisms such as Common Gateway Interface (CGI), since the servlets are loaded once, pooled, and continuously reused. Coupled with early entrance to the marketplace, widespread vendor support, and with the evolution of the JDBC standard, servlets were the first widespread server-based Java environment for accessing relational databases. The JDBC standard provides a vendor-independent mechanism for submitting SQL statements to a relational database management system (RDBMS) for processing, as described throughout this book. JavaServer Pages (JSPs) are an extension to the servlet architecture. JSPs provide the same request and dynamic response function, except authors of the JSPs can generate dynamic content without understanding the Java language. This tag-based language is ultimately translated into servlets for execution. Servlets and JSPs are almost identical from an architectural point of view in that they both are tied to the HTTP protocol, allow for the execution of Java code, are platform independent, and provide dynamic content generation.

90

DB2 for z/OS and WebSphere: The Perfect Couple

The flexibility of the servlet environment does not prohibit business type functions from being embedded into servlets and JSPs. However, such an approach should be seriously considered before implementing. The main goal of a servlet is to provide a dynamic HTML response to an HTTP request. As a result, clients used to invoke servlets can be limited in function, implying that business function embedded in a servlet may be limited to a finite group of clients. We will discuss more robust models for business applications in the Enterprise JavaBeans section.

4.2.1 Benefits of data access from servlets and JSPs


Using servlets provides the benefits discussed in this section.

Reduced CPU cost


Servlets execute within a relatively simple execution environment. Web server vendors are required to provide little infrastructure support for the execution of the Java-based servlet. Servlets are stateless, but have the ability to access stateful resources, such as a relational database, a naming server, or HTTP session data. As a result of their stateless attribute, they are loaded for access by the Web-serving process only once, and can be reused many times. This load-once feature results in an excellent performing execution environment. From a pure CPU per function perspective, servlets likely provide the lowest cost per transaction rate for HTTP requests. As a result, it is possible to implement low cost access to DB2 from a servlet, but be wary of limitations of this approach.

Presentation logic data


For applications that access a relational database only to gather information regarding dynamic HTML content and specifically to use that data as presentation rules, is considered a good approach. Since servlets are tasked with providing presentation to the end user, the methodology of storing Web page layout information within a database is a valid data access approach.

Flexibility and access to entire suite of Java function


Since the full family of Java APIs is available, servlets are extremely flexible in implementation. They have the ability branch into any Java family service including the ability to access relational data stores via JDBC.

Developer-enforced separation of business and presentation logic


If implemented with care, developers of servlets can somewhat separate presentation logic from business logic. Servlets, just like any Java application, are object oriented and can exploit Java classes and libraries that are not tied specifically to the servlet. Such an approach would allow for Java classes containing business function to be reused in different execution environments, including Enterprise JavaBeans, which will be discussed later in this chapter.

4.2.2 Considerations for data access from a servlet


In this section we list some considerations when accessing data from a servlet.

Flexibility
With the flexibility of servlets described above, there is a strong need for tight control of application development techniques to ensure that applications are being developed with good behavior, and to ensure that developers cooperate to reuse software components. Taken to the extreme, each application developer could write his own presentation logic, business logic, and infrastructure for an end-to-end business function within a servlet. The
Chapter 4. DB2 and Java architecture guide

91

servlet could even provide two-phase commit workload, robust security, network-based services, and database access within a servlet. However, this type of service is labor intensive, potentially could be limited to servlet access, and many of the functions could be bought off the shelf from vendors when a different Java approach is used.

Infrastructure
Vendors, such as IBM, focus on providing infrastructure services to support the development, execution, and operation of complex, world class enterprise applications. In many cases, choosing to exploit only servlets and home-grown applications to implement business function increases the applications development cost and potentially hurts performance. Complex function such as failure and recovery are difficult to test, and rarely do developers consider complex and sometimes obscure failure tests. By leveraging a vendor for infrastructure, applications immediately gain the benefits of extreme testing by both the vendor and other customers of the vendor. Consider complex failure and recovery scenarios or incorrectly implemented security. Vendors provide these functions and the quality of their implementations and economies of scale are what drive the lower cost to exploiters of vendor solutions. If it were easy, every company would be in the business of providing application server function. Review 4.3, Enterprise JavaBeans on page 92, for more information on the infrastructure service provided by software vendors, including IBM.

Access protocol dependence


Servlets are almost exclusively tied to the HTTP protocol. While it is possible to call servlets from outside of a Web browser, by far the most common servlet client implementation today is the Web browser. As a result, without rewrite or modification of a servlet-based application, business functions embedded within a servlet are generally limited to being executed by a Web browser. As we will see in the next section, server-based Java components in a J2EE environment are frequently accessed by many different protocols, including other applications instead of human end-users and Web browsers. Consider a Web-enabled cellular phone or another computerit does not make architectural sense to invoke presentation logic in order to execute the embedded business logic.

4.3 Enterprise JavaBeans


As the name implies, Enterprise JavaBeans (EJBs) are a different class of applications in that they are specifically designed to exploit enterprise class services provided by vendors, not repeatedly provided by application developers. By using a standardized application specification and interface, the EJB specification (part of the Java 2 Enterprise Edition specification) application developer can produce applications that are vendor and platform independent, but still exploit best of breed implementations of enterprise services. The applications execute within what is called a J2EE container. The container provides the common infrastructure services via common interfaces. By allowing different vendors to provide the container and the resources accessed by the container, customers can choose the vendor that provides the best value. There is no requirement to use a single vendor for all the components and resources such as a database accessed through the container. Without having to produce these infrastructure functions, application developers can focus on the application logic specific to their business and do not have to focus on how to handle network communications, the security infrastructure, or even database access.

92

DB2 for z/OS and WebSphere: The Perfect Couple

Below are some select EJB infrastructure services a container must provide according to the J2EE specification: Location transparency so that Java objects can be accessed on remote servers as if they were local Transaction support including two-phase commit support for accessing multiple EJBs at multiple physical locations and for accessing multiple resources (resource managers) in the same unit of work A JDBC interface for database access Container managed database persistence (for Container Manager Persistence entity Beans) Security infrastructure for authentication and authorization Exception handling for error handling Java Naming Directory Interface support to help provide abstraction for all resources referenced in the application These functions are accessed via a standardized API. When the application is deployed, a deployment descriptor is used to detail to the container the implementation of these services. While within the application, JDBC access has a generic interface to communicate with a database; and the deployment descriptor gives the container specific information regarding which data source the application is exploiting, what the underlying database vendor supports, at what physical location the database is, etc. The deployment descriptor will also frequently determine how transactions and security are implemented. Since EJBs have standardized mechanisms for invocation, as new protocols and standards evolve, vendors implement mechanisms to leverage pre-existing EJBs from the new protocol or paradigms. From the origins of the EJB standard, an HTTP request could trigger a servlet to call an EJB. Also, EJBs have always had a standard remote interface for Java clients, known as Remote Method Invocation (RMI). As new standards have emerged, the new technologies have been fully embraced by the EJB specification and vendors implementing containers. For example, message-driven Beans are a recent addition to the EJB specification. These Beans allow the invocation of existing EJBs by an asynchronous message-based request. Web Services, described in 4.13, Web services on page 104, allow the invocation of EJBs by clients that are not even Java compatible. If the business logic in these EJBs were implemented in traditional programming paradigms, it is likely that the applications would need significant re-architecture to be leveraged. EJBs allows new applications to leverage existing business logic built according to the EJB specification. All application functions, not only database access, can benefit from these services implemented by a container. The J2EE specification breaks application actions into different EJB types. Each interact and are managed by the container in a different manner. Session Beans provide actions and generally contain business logic. Entity Beans represent data that transactions and business logic act upon. These Beans are defined in more detail in the following sections.

4.4 Session Beans


A session Bean can be considered an extension of the calling client, which in some cases can be on a different physical platform or tier. For remote (or local) clients, the standard interface for working with a session Bean allows location transparency. For performance reasons, session Beans also provide local interfaces when applications can ensure that Beans will be deployed within the same container.

Chapter 4. DB2 and Java architecture guide

93

From an application design perspective, session Beans can be considered analogous to a verb. Session Beans should be used to perform some action or carry out a transaction. Session Beans are frequently the first EJB referenced within the container from external clients such as a servlet. The session Beans provide a business action interface for presentation layers to invoke. In robust applications, multiple layers of session Beans can be used to provide a function; see 4.11, Session facade pattern on page 102, for more information. As an EJB, session Beans benefit from the infrastructure provided by the EJB container. They allow developers to focus on providing business function without the need to programatically handle security, transaction management, network access, etc. In many implementations, session Beans act as the gateway to application functions and are responsible for sending (marshalling) incoming requests to the right business functions implemented in other session Beans. Since they are frequently the entry point to the server, they generally control where security policies are enforced and transactions begin and end. Exploiting these infrastructure services can be implemented manually by the application developer, but are generally not programatically performed. Instead the infrastructure functions are implemented as part of the session Bean deployment descriptor.

4.5 Stateless session Beans


The stateless attribute means that the Bean does not maintain a conversational state with the calling client. After a method is called and a response is sent to the client, the Bean is pooled and fully available to other callers and all data. Once the call is complete, all information regarding the client and actions taken within the method call is lost. All of the pooled instances of stateless session Beans are indistinguishable.

4.5.1 Benefits of data access from a stateless session Bean


Let us look at the benefits of using a stateless session Bean.

Full EJB container exploitation


Stateless session Beans can exploit the full set of functions in the Java and Enterprise JavaBean specifications. Stateless session Beans can implicitly exploit full transaction support provided by the container and reduce the amount of user code required to provide robust enterprise services as described above.

Stateless scalability
Since stateless Beans are stateless and non-conversational, there is a significant performance and availability benefit. After a method invocation, the session Bean is fully available for any other client without the need to persist session-specific data. This is especially useful in a clustered Web server environment, such as WebSphere. Since every request is generic, any request can be routed to any specific server instance in the cluster that supports the stateless session Bean. This allows stateless session Beans to scale extremely well both vertically and horizontally. In almost all cases, the scalability limitations for stateless session Beans are dictated by common resources access outside of the container such as the relational database.

Stateless failover
Since the session Bean has no state, a server failure or recycle simply means that requests can be routed to other session Bean instances at other application server instances in a clustered environment. This provides premium server failover characteristics. 94
DB2 for z/OS and WebSphere: The Perfect Couple

Full SQL control and function


For database access, a session Bean can exploit the JDBC specification with full SQL control. Coupled with the container, the session Bean is similar to a traditional transaction manager with direct access to a relational datasource. This implementation is extremely similar to CICS access to DB2. In implementations with direct JDBC access, the session Bean represents a transaction or action for the client to invoke. The session Bean can access the relational database with knowledge and understanding of the database schema. The session Bean places no requirements for the database different than other transaction environments, for example, an application could choose a highly normalized or denormalized database schema.

Order of operations control


High-performance access to an RDBMS usually requires that tables are manipulated in a specific order within a transaction to help avoid locking conflicts and deadlock scenarios. Stateless session Beans provide full control over table access since the actions against the table are directly implemented by the application developer.

Coexistence with non-EJB applications


Since the transactional and functional nature of a stateless session Bean access to DB2 is similar to other applications that access DB2, such as CICS, session Beans can frequently access a relational database in conjunction with other transaction managers. This is a result of session Bean application developers using the same online transaction processing techniques as non-Java transaction environments. A JDBC developer, specifically controlling the application and its SQL, can focus on minimizing lock duration, using appropriate isolation levels, reducing the number of tables accessed, selecting only the appropriate columns with the appropriate access intent, etc. This results in the same highly scalable characteristics of traditional, non-z/OS OLTP applications.

Access protocol independence


As mentioned in 4.3, Enterprise JavaBeans on page 92, as new protocols and methods of accessing data and functions evolve, either within or out of Java specifications, vendors will implement code to bridge between the new protocols and the existing EJB infrastructure. This will allow organizations to leverage existing data access and application logic within session Beans as new computing paradigms evolve.

4.5.2 Considerations
Following are some considerations when using stateless session Beans.

Application developer SQL skills


One of the goals of the J2EE specification is to reduce the infrastructure skills required by an application developer. At a gross level, database access is simply storing data, a function almost every application needs to perform. As a result, data access can be considered an infrastructure service. As we will see in 4.9, Container-Managed Persistence entity Beans on page 100, there are EJB implementations that follow this approach and include automatic underlying interaction with the database, hidden from the developer. Alternatively, the stateless session Bean with direct JDBC access continues the traditional approach of exploiting intimate knowledge of database structures, locking behavior, and database schemas to provide enhanced performance for OLTP applications. In this respect, the requirements to understand the details of JDBC, SQL, and OLTP application behavior techniques can be viewed by some as a negative characteristic since the skills may not be

Chapter 4. DB2 and Java architecture guide

95

readily available. In some applications, highly scalable and well behaving applications are simply not required, so session Beans may cause a burden on application developers.

Relationship implementation
Relationships between tables and data need to be implemented within the session Bean. It is common for session Beans to implement a data access layer that will allow columns within a database to be instantiated into Java objects. The objects are then used by the business portion of the application, and then when object attribute changes occur, the objects are externalized using the data access layer (see 4.15, Java Data Objects on page 104). It is important that actions against the data representing objects are valid from a data relationship perspective. This means that session Beans, just as other function-based transaction managers, require that transactions understand the relationship between the multiple tables and data within, but if using a data access framework, the relationships will extend into the Java objects as well.

4.6 Stateful session Beans


Unlike stateless session Beans, stateful session Beans are conversational in nature. When accessing a stateful session Bean, clients retrieve a Bean handler, which uniquely identifies the instance of a stateful session Bean they are working with. The client can use the handle to execute multiple methods with the same Bean within the same transaction. The Bean is able to store variables and state across the multiple method executions. The requirement to maintain session Bean status at the server for stateful session Beans proposes some real-world challenges. Under high volumes, servers have the potential to experience resource constraints. As a result, the EJB specification states that the container may invoke life cycle methods on stateful session Beans. These life cycle methods allow the container to swap a Bean out of storage to free memory, CPU, or other resources if physical limitations of the machine are constrained. This allows the server to allocate resources to other users while waiting for the next instruction from the client. If a stateful session Bean instantiates any objects, a container does not know how to automatically persist to disk. The application developer must specifically provide a mechanism to store and subsequently retrieve any required session resources. This is accomplished via standards-based passivate() and activate() methods. Within these methods a developer is responsible to implement storage mechanisms for variables that are not Java serializable, database connections, and some other types of resources beyond the scope of this book. In general, the use of stateful session Beans, especially directly by remote clients, is not considered a best practice.

4.6.1 Benefits of stateful session Beans


Let us first look at the benefits of using stateful session Beans. They are similar to using stateless session Beans.

Full SQL control and function


See Full SQL control and function on page 95.

Full EJB container exploitation


See Full EJB container exploitation on page 94. 96
DB2 for z/OS and WebSphere: The Perfect Couple

Access protocol independence


See Access protocol independence on page 95.

Order of operations control


See Order of operations control on page 95.

Coexistence with non - EJB applications


See Coexistence with non - EJB applications on page 97.

4.6.2 Considerations
Let us now look at the major considerations when using stateful session Beans.

State management
For variables and objects that the container can automatically passivate and activate, the container is configured to externalize the variables out to a WebSphere-managed session area (passivation directory). For WebSphere Application Server for z/OS, the session area is within a shared file system. Although transparent to the application and unlikely to occur with a high frequency, these stateful objects undergoing life cycle management can cause extra I/O to shared resources and may degrade performance.

Connection management
One of the resources that the container cannot automatically passivate and activate is database connections. A stateful session Bean then must provide logic to implement, create, and destroy connections within the passivate/activate section, or make database connections non-session based, and have each method create and destroy a connection.

Transaction management
Since the Bean must be able to activate and passivate the connection, transaction management may become more difficult. If the transactions need to span the entire life span of the conversation, or across multiple method calls, then an activate mechanism must be in place to re-establish the exact state of the transaction before it was passivated. This can be a difficult or poor-performing task. Consider the case where each method within a connection issues a DB2 update, with all method calls in a single transaction. If the Bean were to be passivated, the connection and the transaction would need to end and upon activation. A replay of all events would need to occur.

Affinity routing requirement


WebSphere for z/OS does not support the cloning of specific stateful session Bean instances across multiple application servers. As a result there is a direct affinity between a session Bean client and the application server executing the session Bean. This reduces the servers availability to perform workload distribution across a cluster and the associated performance benefits found in a stateless model.

Availability
Since the stateful session Bean is tied to a specific server, if the server fails, the entire Bean fails and the request cannot be re-routed to an alternate server. The client must handle retry of the function.

Chapter 4. DB2 and Java architecture guide

97

4.7 Entity Beans


Entity Beans are J2EE representations of data. If session Beans are verbs that provide a service or perform an action, entity Beans represent a noun. Entity Beans are a specific item or object on which actions can be taken upon. For example, an application that updated a customers address might be broken into two types of EJBs. The session Bean would provide an updateAddress function, while the entity Bean would be the actual representation of a customer that is updated by the session Bean. Since the entity Bean actually represents data, the variables within the Bean can be mapped to relational database tables. While a relational database is not required to be used as the backing store for entity Beans, it is by far the most common implementation. By definition of the EJB specification, entity Beans provide a standardized interface for business application developers to reference and manipulate data without the need to understand the underlying database or database structure storing the data. The actions a developer can take against an entity Bean can be logically mapped to DB2 table access. Referencing an entity Bean equates to an SQL select, Bean creation is an SQL insert, Bean deletion is an SQL delete, and updating the fields within the Bean results in an SQL update. The actual persistence layer that accesses DB2 is independent of how the business logic developers interact with the entity Bean. All entity Beans use a primary key reference to identify the particular instance of the Bean they are attempting to select. This equates to a key on the DB2 table. An entity Bean can be directly accessed using the primary key; or when the key is not known, a custom finder can be defined to search through the database for the requested entity. In the case of a customer Bean, the customer may have a customer number as a primary key. When a customer is looked up by last name and birth date, a custom finder on last name and birth date may return the customers primary key, which then allows the application to instantiate the Bean using the primary key. Without such finders, every Bean in the table would need to be instantiated in order for an application to reference the entity Bean instance without knowing the primary key. Entity Beans, like all EJBs, also benefit from the transaction, location, and security infrastructure support of the container. Entity Beans can participate in transactions, and since there is an abstraction between the entity Bean and how it is stored, the container can transparently provide access to multiple distinct underlying databases responsible for persisting different Beans, which may all be updated within the same transaction.

4.8 Bean-Managed Persistence entity Beans


Entity Beans are broken into two major classes based upon how the data within the entity Bean is persisted. Bean-Managed Persistence is an approach where the entity Bean provider needs to implement a set of Java methods specifically for the container to call, when a Bean needs to be created, updated, deleted, or referenced. These methods are known as call back methods since they are not exploited by the application but instead exploited by the container. In the Bean-managed persistence model, the Bean provider is required to provide application code to propagate changes in the entity Bean into the relational database.

4.8.1 Benefits
We first have a look at the benefits of using Bean-managed persistence EJBs.

98

DB2 for z/OS and WebSphere: The Perfect Couple

Forced data access abstraction


The standardized API forces business application developers to interact with entity Beans with an interface that hides the underlying persistence layer used to store the data. This is valuable in that it allows changes in portions of the application without affecting the entire end- to-end application.

Flexibility in SQL programming


Since the Bean provider is required to build and execute the persistence layer, the Bean developer has the ability to choose any persistence mechanism he wishes, including SQL via JDBC, SQL via SQLJ, stored procedure calls, or Java Data Objects, as described in 4.15, Java Data Objects on page 104. While in theory the flexibility allows for almost any database schema to be exploited, due to data relationships and the nature of object-oriented languages, entity Bean persistence usually dictates that the attributes of an entity Bean comprise a table. This enforces a one-to-one relationship between entity Bean attributes and table columns, and a one-to-one relationship between rows and entity Bean instances.

Full EJB container exploitation


See Full EJB container exploitation on page 94.

Access protocol independence


See Access protocol independence on page 95.

4.8.2 Considerations
Now let us look at some of the important considerations when using Bean-managed persistence EJBs.

Order of operations not maintained


Since the application code that accesses the relational data store is invoked by the container based upon actions by the EJB client, it is impossible to control the order of access to tables from within an individual Beans persistence code. This is because a session Bean may access multiple entity Beans in any order it chooses and the persistence code within a Bean only persists the data in the entity Bean it is defined within. This can sometimes make it difficult to ensure that deadlock scenarios will not occur. In addition, the SQL used to perform persistence frequently requires exclusive locks to guarantee data integrity. These locks are generally incompatible with other applications that update data. As a result, other insert/update/delete applications outside of the EJB are generally prohibited.

Bean provider SQL skills


See Application developer SQL skills on page 95.

Relationship implementation
See Relationship implementation on page 96.

Affinity routing requirement


Since the Beans represent data, any reference to the specific instance of an entity Bean while it is being referenced by any application must be routed to the same application server that is

Chapter 4. DB2 and Java architecture guide

99

managing the entity Bean. See Affinity routing requirement on page 97 for additional information. This prohibits workload distribution across a clustered server environment.

4.9 Container-Managed Persistence entity Beans


Container-managed persistence entity Beans (CMP) differ from Bean-Managed Persistence (BMP) in that the CMP model requires that the Bean provider (application developer) simply maps the attributes of the entity Bean to columns in a RDBMS. With the advanced tooling available today, its possible to take a Bean and automatically generate the underlying database definition and all SQL used for persistence. Alternatively, the database DDL can be provided and an entity Bean can be automatically generated based upon the database model. The container generates all of the SQL used to access and manipulate the data within the table. Again, the business application developer does not need to be aware of how the entity Beans are persisted in the relational database. The SQL statements are completely hidden from all of the developers.

4.9.1 Benefits
As before, we first look a the benefits.

Reduced programming cost


With a direct mapping between the tables and the Bean attributes, and the container generating all of the underlying SQL, the cost of developing an application, as well as the time to market can be reduced.

Checkbox SQLJ exploitation


When using the WebSphere Studio Application Developer (WSAD) application development environment, the persistence code can be generated using static SQLJ instead of JDBC for persistence, by simply checking an option during the persistence code generation. This allows the EJB application to exploit the performance benefits of static SQL, as well as take advantage of the static security model benefits of the SQLJ model, without the need to explicitly code this within its application.

Relationships
Relationships are a recently added function within WebSphere, and are also part of a new edition to the EJB specification. Relationships extend referential integrity relationships in databases into the container. This enforces object-based relationships in the application to ensure that applications interact with session Beans correctly. The relationships can be derived from the referential integrity relationships in the database or defined as part of the deployment descriptor.

Full EJB container exploitation


See Full EJB container exploitation on page 94.

Access protocol independence


See Access protocol independence on page 95.

100

DB2 for z/OS and WebSphere: The Perfect Couple

Functional enhancements exploitation


Since the persistence code is generated by tooling and not by a developer, if new tooling is provided with functional or performance enhancements, a redeployment of the application will allow full exploitation of the new function without updating the application. SQLJ support is an example where CMP Beans are able to leverage the SQLJ model without changing any code due to improvements in tooling support.

4.9.2 Considerations
Let us also look at some considerations related to CMP Beans.

Reduced application co-existence


As a general rule, CMP Beans do not allow coexistence with other applications. This is because the container controls locking based upon how your Beans are deployed. With lots of subtle rules on database access and optimizations used for caching, it is generally not recommended that applications attempt to reference databases used for CMP persistence. Under the default deployment descriptors, data is selected with rs keep update locks, even if the data is not going to be updated. The general model is that once the data is selected from the database, the container will control all access to the data. This locking approach makes it generally difficult to access and update data from outside of the container.

Diagnosis skills
While the implementation of CMP Beans has certainly improved, without intimate knowledge of the underlying persistence model, it can be difficult to identify where defects are occurring and provide corrective action.

Database schema
CMP datastores generally need to be highly normalized. Since all access to the database occurs through a single Bean, there should be a one-to-one mapping between a table and an entity Bean. This also makes it difficult to exploit an existing database for use with CMP Beans.

Configuration complexity
There are many deployment descriptors that ultimately affect how persistence code is implemented in the container. Since the specific behavior is hidden from the application developer, it is difficult to understand what the cause of inappropriate behavior is. In many cases, vendor-specific deployment descriptors can have a major impact on how the SQL is generated. In addition, each RDBMS has different locking characteristics, and controlling lock contention can be a challenge in an environment where you do not control the underlying SQL functions.

4.10 Message-driven Beans


While not directly relevant to database access, message-driven Beans (MDBs) provide an additional mechanism for executing business logic and entity Beans within Enterprise JavaBeans. The MDB is an asynchronous message sender and/or receiver function that is similar in function to IBM WebSphere MQ Series. MDB support is fully transactional, meaning that the pulling of a message from a queue and subsequent access to a relational database can be atomic. The container provides a full-time listener service that will invoke a Bean when a message arrives on a queue. In addition, messages can be sent to a queue for asynchronous delivery.
Chapter 4. DB2 and Java architecture guide

101

A common implementation of an MDB would be to receive a message from a queue that invokes a transaction within a session Bean, which subsequently performs some action against a database.

4.11 Session facade pattern


For the EJBs described above, it is worth noting the following common practice within J2EE applications. A pattern known as a session facade ensures that all access to business functions and data is initially passed through an outside world facing servlet. The servlet inspects requests through a simple interface and then invokes the proper servlets (and potentially entity Beans if exploited). Using this facade gives a simple face to clients and hides the underlying implementation of business functions. The session facade can also provide the control point for security and stating/ending transactions. When manipulating a relational database it is imperative to limit the duration of transactions as to reduce lock duration. Lock durations should always be considered for applications that require high availability, and a session facade allows an application server to potentially limit transaction scopes to within the application server. More information on session facade can be found at:
http://java.sun.com/blueprints/patterns/SessionFacade.html

4.12 Stored procedures


Stored procedures (SPs), a feature of DB2 and almost all relational databases, provide an execution environment physically and logically collocated with the relational database. Among other interfaces, stored procedures can be invoked by Java applications using a standard interface that is part of the JDBC specification and is fully supported within J2EE environments. Generally stored procedures are invoked from within an EJB container by a session Bean. Logically, stored procedures provide some form of business logic or an action against data and as result map extremely well to a stateless session Bean.

4.12.1 Benefits of accessing data from stored procedures


First we look at the benefits of using stored procedures.

Reduced network traffic


Stored procedures were originally designed as a mechanism to reduce the amount of network traffic required between an application and a database server. The SP application execution environment allows business logic to work against many rows of data and subsequently return an acknowledgement of work completed, or return a small result set of data back to the calling application. This reduces network time, which is helpful for overall application performance, and specifically useful in relational databases for reducing lock duration and increasing overall concurrency. This philosophy also holds true for Web-based applications, which execute at a different server than the LPAR where DB2 resides.

Stored procedure reuse


In rare scenarios, new applications are developed from scratch with new databases. The more common scenario is that an existing application must be modified, or at least its

102

DB2 for z/OS and WebSphere: The Perfect Couple

database must be leveraged. In some of these cases, it may be appropriate to reuse business function already included within a stored procedure. In addition, new stored procedures developed for a J2EE application can also be executed by applications outside of the J2EE environment.

Efficient programming language


Historically speaking, the Java programming language was significantly less efficient then other programming languages, especially on the z/OS platform. However, recent enhancements in the Java Virtual Machine on z/OS and changes in the pricing paradigms on zSeries have dramatically reduced this benefit. zSeries Application Assist Processors (zAAPs) have changed the cost benefit for writing stored procedures in low-level languages to save CPU costs. The zAAPs provide the same function as other zSeries CPUs except they only execute Java functions. Since they are limited to Java application code execution, the price of a zAAP is significantly less then the cost of a standard CPU. In addition, zAAPs do not incur the standard MSU software maintenance costs. in addition to IBM, this maintenance policy has been adopted by the bulk of the independent software vendors. From a hardware perspective there may be some benefit in providing stored procedures to execute complex business function in a low-level language, but most of the business justifications have been removed with the changed pricing models.

Static execution model


While static SQL is available in the Java language via SQLJ, which is supported in every one of the JavaBean types described in this chapter, many Java developers choose to use JDBC since it is the more common implementation. Exploiting stored procedures, a DBA could provide static stored procedures for the Java developer to exploit. This would give the application all the benefits of a static SQL execution model, repeatable execution, reduced prepare cost, and a static security model.

Utility or maintenance function


Stored procedures can be used to execute data maintenance tasks, such as data scrubbing, which massages many rows of data. DB2 also provides stored procedures for invoking database utility functions, such as image copies and reorganizations, so data maintenance can be activated through the invocation of a stored procedure.

Gateway to other resources


Since not every resource may have accessibility from a Java environment or from distributed requestors, stored procedures can be used as a pass-through mechanism to other zSeries-based resources. For example, DB2 supplies sample user-defined functions for accessing WebSphere MQ and stored procedures for accessing CICS and IMS transactions.

4.12.2 Considerations
Next we look at some stored procedure considerations.

CPU cost to switch context


Executing stored procedures requires some extra CPU costs in order to switch contexts into the stored procedure execution environment. When executing a Web server on the same logical partition (LPAR) as DB2 UDB for z/OS, this extra overhead needs to factored into any

Chapter 4. DB2 and Java architecture guide

103

perceived performance benefits for executing a stored procedure. Unless network time and traffic is reduced, this will result in increased elapsed time.

4.13 Web services


While not specifically related to the task of data access, it is worth noting that Web services are part of the J2EE specification, and allow the invocation of EJBs from non-Java clients. The Web service paradigm allows a business function to be published as an available service in a service directory that other applications can exploit. The services are described with a standardized self-defining language. The description, known as Web Services Definition Language (WSDL), provides instructions on what functions the service provides and how consumers should interact with the service. Web services are generally accessed via an asynchronous message, formatted using the Simple Object Access Protocol (SOAP), an XML-based message that is sent over HTTP. The SOAP message allows requests for functions to be sent, and responses to be received by the client application, known as a consumer. From a database architecture perspective, the important notion is that your database can be made accessible to non-EJB clients, who ultimately pass through an EJB before accessing DB2. This is an example of the continued evolution of computing paradigms that will be supported by the EJB specification and its supported vendors.

4.14 SQLJ support


SQLJ is available from every type of Java access to DB2 described in this chapter. SQLJ is a simple programming API that provides static SQL execution performance, repeatability, and security. See Chapter 7, SQLJ on page 139, for additional information.

4.15 Java Data Objects


Java Data Objects (JDOs) is a framework for mapping and manipulating Java objects in a relational database. Not officially part of the J2EE specification, this Java infrastructure allows a programmer to exploit a framework for persistence. The application developer is able to pass objects to the framework for persistence and does not have to worry about the specifics of the SQL used for persistence. At a gross level, a JDO is similar to a CMP entity Bean. However, JDOs do not provide the functions available within a container and is not a competing technology; instead, it is a complementary technology. For architectures that are session Bean only, JDOs offer a mechanism for managing and implementing a data persistence layer. Some EJB container providers are considering the use of JDOs for providing CMP entity Bean persistence, but this would be transparent to application developers. For more information, see: http://java.sun.com/products/jdo/index.jsp

104

DB2 for z/OS and WebSphere: The Perfect Couple

4.16 EJB Beans summary


When reviewing the different options for which types of Beans should be responsible for accessing DB2 data, and how those Beans should be referenced, it is clear there is a lot of flexibility and that there are many choices. In general, Beans at a given location are referenced via a stateless session Bean, which then passes requests to either other business logic session Beans, which ultimately either access session Beans for data access, or to entity Beans. Beyond that first stateless session Bean, there are two general implementations: The pure stateless session Bean approach where individual transactions provide their own database access; or, alternatively, session Beans that reference entity Beans. Multiple factors affect the decision, but many people agree that if you require high OLTP support, session Bean access is generally more scalable, but does require significantly more application development time and skills. In Table 4-1, we attempt to summarize the benefits and considerations when using each of the different access methods for data.
Table 4-1 Data access comparison Data access component Servlet Benefits Reduced CPU cost Flexible Good for accessing presentation layer attributes in a relational database Considerations No or little supporting infrastructure for common enterprise applications (transaction, security, jndi, persistence, etc.). Potentially too flexible (no enforcement of separation of presentation and business logic). Generally only accessible from HTTP requests, not other protocols. JSP Same as servlets Java language skills not required Same as servlets. Script/tag interface that is ultimately translated to a servlet before execution. Notes Java code that is generally tied to HTTP requests that respond with dynamic HTML content and can invoke the full family of Java functions, including JDBC.

Chapter 4. DB2 and Java architecture guide

105

Data access component Stateless session Bean

Benefits Full EJB infrastructure exploitation Similar development paradigm as CICS, or other transactional-based environments Robust protocol access Stateless scalability Stateless failover OLTP SQL techniques for high scalability can be implemented by application developer No restrictions on data schema Can concurrently execute against data with non-Java OLTP applications

Considerations Data access is implemented by Java code and requires SQL expertise. Must implement data relationships via SQL.

Notes

Stateful session Bean

Same as above

Same as above. Non-transient database connections and transactions must be implemented in passivate/activate. State management overhead.

Similar in function to a stateless session Bean, except that the client maintains a conversation with the Bean. The Bean maintains data across the entire conversation.

Entity Bean (BMP)

Full support of container infrastructure Robust protocol access Enforced separation of application layers

Relationships need to be implemented. Limited database schema. Limited co-existence. Affinity routing.

106

DB2 for z/OS and WebSphere: The Perfect Couple

Data access component Entity Bean (CMP)

Benefits Full support of container infrastructure Robust protocol access Enforced separation of application layers Checkbox SQLJ support Automatic support for future enhancements through regeneration Relationships can be implemented by container

Considerations Affinity routing. Black box diagnostics. No application co-existence. Limited database schema support.

Notes

Stored procedure

Can be written in any language Can be collocated with the data Can be shared by non-Java applications Can leverage existing SP Reduced network traffic Excellent for batch type functions that require manipulation or inspection of many rows; can significantly reduce cost of Java object creation Can be used to invoke DB2 utility functions and maintenance operations Gateway to other zSeries resources

May incur additional unnecessary overhead for local Web servers. Does not have access to container services such as naming server. SPs are not session oriented (do not maintain state).

Persistence code locking behavior may prohibit a stored procedure from concurrent insert/update/delete activity against the same data CMPs or BMPs access.

Chapter 4. DB2 and Java architecture guide

107

108

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 5.

DB2 application development in a WebSphere environment


This chapter discusses influential factors when developing DB2 applications using JDBC and SQLJ. In addition, we look at the ability to set parameters that influence DB2 applications from a WebSphere environment. This chapter contains the following topics: Figure 5.1 on page 110 JDBC application programming concepts SQLJ application programming concepts Preparing JDBC and SQLJ applications for execution Impact of different DB2 bind options on Java applications Special registers

Copyright IBM Corp. 2005. All rights reserved.

109

5.1 JDBC and SQLJ application programming comparison


DB2 UDB for OS/390 and z/OS Java programs run in the z/OS UNIX System Services environment. The general program flows of JDBC and SQLJ applications are very similar. There are, basically, six phases: 1. 2. 3. 4. 5. 6. Access or import the Java packages that contain JDBC methods. Declare variables for sending data to, or retrieving data from, DB2 tables. Connect to a data source. Execute SQL statements. Handle SQL errors and warnings. Disconnect from the data source.

This chapter does not focus on the details of the program flow phases. They are thoroughly discussed in Chapter 7, SQLJ on page 139, and also documented in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414. This section does point out some fundamental differences between JDBC and SQLJ.

5.1.1 JDBC and SQLJ compared


Generally, Java applications use SQLJ for static SQL and JDBC for dynamic SQL. Both JDBC and SQLJ can be used in the same application. The question that usually comes up in the planning phase of a Java application that needs to be able to communicate with DB2 UDB for OS/390 and z/OS, is whether to use JDBC or SQLJ. Table 5-1 lists considerable differences, which can help determine whether JDBC or SQLJ is the best solution for your particular application and environment. Keep in mind that both JDBC and SQLJ have the patented Java trait of being portable across platforms.
Table 5-1 Comparison of JDBC and SQLJ characteristics JDBC characteristics Dynamic SQL model is used. Is an application program interface (API). Translation and bind are not performed. SQLJ characteristics Static SQL model is used when customized. Is a language extension. Program preparation includes source code translation, optional (but highly recommended) customization, and subsequent bind. Authorization checking against the ID of the package owner is performed at bind time. Data types are checked during the program preparation process. Smaller source programs when compared to equivalent JDBC programs, as SQLJ automatically generates certain required code. Java host expressions can be embedded in SQL statements.

Authorization checking is performed against the ID of the user at run time before an SQL statement is executed. Data types are not checked at compile time. Developer must include certain code in JDBC programs resulting in larger source code when compared to equivalent SQLJ source code. A separate statement is required for each bind variable and specifies the binding by position number.

110

DB2 for z/OS and WebSphere: The Perfect Couple

5.1.2 Best practices


Although there are some instances when JDBC may be more appropriate, the following topics provide some insight as to why SQLJ is highly regarded, and recommended, as the DB2-Java application programming solution, especially in a DB2 for z/OS environment.

Superior performance with customized SQLJ


Customized SQLJ reaps the performance benefits associated with the static SQL model. Authorization checking against the user ID running the program is the only step performed before executing the SQL statement. As opposed to JDBC and dynamic SQL, there is no need for DB2 to parse the SQL statement and determine an access path each time the SQL statement is executed at run time. With SQLJ, as illustrated in Figure 5-1 on page 118 and Figure 5-2 on page 119, this is done only once during bind time, thereby avoiding the performance hit at run time for each execution. In large part, this is the reason why customizing SQLJ applications, although an optional step, is highly recommended. However, running uncustomized SQLJ can have its place as well. Uncustomized SQLJ applications are treated as dynamic SQL at run time. This means that, at run time, the SQL statement will be parsed and an access path will be calculated each time the SQL statement is executed. This can be very beneficial during the development phase of an SQLJ application. It also provides an excellent testing ground for performance tuning if you wish to run different flavors of SQL statements. After determining optimal SQL statement performance, you can customize the SQLJ application, which will then run as static SQL. This is one very nice advantage of using SQLJ.

Improved authorization control


The ability to perform authorization checks at the program level is another benefit of running SQLJ applications within the static SQL model. When using dynamic SQL, the user ID under which the program is run must have all the necessary privileges required to execute each SQL statement in the program. For example, take an application that uses dynamic SQL to insert rows into a table, update rows from another table, and delete rows from a third table. In this scenario, each user ID that runs the program requires a minimum INSERT, UPDATE, and DELETE privilege on the specific DB2 table the SQL statement references. When running dynamic SQL programs, granting privileges at the user level is a major security exposure. This is because the user has the authority to utilize those same privileges at any time. They are not restricted to only running the program. Once the user has been granted the necessary privileges and a connection has been established to the DB2 subsystem, there is nothing protecting the tables from being manipulated by the user. Instead of using the Java application, a user can also use any other tool to access the data. Another issue related to programs running dynamic SQL is managing the authorized user IDs. Although this task can be somewhat circumvented by using group IDs, and granting the necessary privileges to the group IDs, it remains a tedious, and potentially unforgiving task if done incorrectly. This security exposure can be addressed when using the static SQL model. With static SQL, any given user requires only the EXECUTE authority on the application package (or DB2 plan), instead of all the privileges to execute INSERTs, UPDATEs, and DELETEs against the DB2 tables. The user ID of the owner of the package (or plan) is used for authorization checking against SQL statements executed by the application. The user ID of the person

Chapter 5. DB2 application development in a WebSphere environment

111

executing the application is not used for authorization checking against the SQL statements. In summary: Only the user ID of the package owner requires the necessary privileges to run all the SQL statements in the application. DB2 bind options are discussed further in 5.5, Impact of different DB2 bind options on Java applications on page 120. Users who need to run the application only need the EXECUTE authority against the package (or plan). They do not have or need any additional privileges against the DB2 tables used by the application. This eliminates the possibility of the user being able to modify the data in the DB2 tables at any time, using any other tool that allows them to connect to the database. Only granting EXECUTE authority to users who need to run the application, and only granting the necessary privileges to the applications BIND OWNER, ensures that the data can only be modified under approved business controls. When using type 2 connectivity, a user requires EXECUTE authority on the application plan to run the program, as opposed to having EXECUTE authority on the package. The application plan then includes the appropriate package(s) in the PKLIST bind parameter. However, the same security concept applies. Authorization still occurs at the program level and not at the user level. (Remote applications use a system plan called DISTSERV. No explicit authorization to execute the DISTSERV plan is required. You only need to be able to execute the remote package that your application is referencing.)

Easier to code, read, and manage


As a language extension, SQLJ is efficiently integrated with the Java code. JDBC, as an API, must wrap SQL statements in Java methods. Generally, SQLJ is visually easier to follow in terms of program logic, as the SQL statements are not wrapped in a Java method. Additional benefits of an SQLJ application include: Uncomplicated host variable management. It is easier to define, maintain, and access host variables in SQLJ than in JDBC. SQL syntax errors are caught by the SQLJ translator (sqlj) and customizer (db2sqljcustomize). With JDBC, syntax errors are caught at run time. Partial code explicitly required in JDBC programs is automatically generated with SQLJ programs. When customized and bound, the access paths of an SQL statement are predetermined. This allows for increased performance tuning, and eliminates the potential for incorrect results or long-running queries at run time. Fully supported by WebSphere Studio Application Developer (WSAD) V5.1.

5.2 JDBC application programming concepts


This section assumes that the JDBC application is using the IBM DB2 Universal Driver for SQLJ and JDBC (com.ibm.db2.jcc.*). 1.9, Using the DB2 Universal Driver for SQLJ and JDBC on page 26, provides information on how to install the DB2 Universal Driver. Detailed information about the installation process can also be found in DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

112

DB2 for z/OS and WebSphere: The Perfect Couple

5.2.1 Java packages for JDBC applications


Usually, there are Java packages that need to be imported when writing JDBC applications: java.sql - The core JDBC API javax.sql - JDBC 2.0 standard extensions javax.naming - Classes and interfaces for Java Naming and Directory Interface (JNDI) Not all JDBC applications will require all classes or interfaces within a Java package to be imported. Example 5-1 shows the basic syntax when importing Java packages in a JDBC application using the DB2 Universal Driver.
Example 5-1 Importing classes in a JDBC application import java.sql.*; // JDBC base import javax.sql.*; // JDBC 2.0 standard extension APIs import com.ibm.db2.jcc.*; // DB2 Universal JDBC Driver interfaces

It is worth noting that importing does not really load any code. It only allows you to use a short-hand notation when referencing the classes incorporated in the imported packages. Finding the actual classes at execution time is done based on the CLASSPATH information.

5.2.2 Using the DB2 Universal JDBC Driver and the DataSource interface
The DataSource interface was introduced with the JDBC 2.0 specification and resides in the javax.sql package. A DataSource object is a factory for Connection objects. The implementations of the DataSource interface offered by the DB2 Universal Driver are: com.ibm.db2.jcc.DB2SimpleDataSource This is the simplest data source provided by the Universal Driver. It is not enabled for connection pooling, nor does it support distributed transactions. It can be used with type 2 or type 4 connectivity. This datasource does not support type 4 XA connectivity. com.ibm.db2.jcc.DB2DataSource This is a data source with a rudimentary pooling manager. com.ibm.db2.jcc.DB2XADataSource A factory for XA connections. The DB2XADataSource, DB2XAConnection, and DB2Xid interfaces provide all the things needed by a JTA implementation. These interfaces are currently supported for type 4 connectivity. This datasource supports connection pooling provided by WebSphere Application Server or another application server. It supports distributed transactions. com.ibm.db2.jcc.DB2ConnectionPoolDataSource A factory for pooled connections. The DB2ConnectionPoolDataSource and DB2PooledConnection interfaces provide all the necessary hooks to implement a connection pooling module. This datasource is used by the WAS pooling module. 3.3, Data source definitions in WAS V5 on page 51, provides additional details on using DataSource objects in a WebSphere environment. Note: From a WebSphere Application Server for z/OS standpoint, only com.ibm.db2.jcc.DB2ConnectionPoolDataSource and com.ibm.db2.jcc.DB2XADataSource DataSource are exposed.

Chapter 5. DB2 application development in a WebSphere environment

113

An object that implements the DataSource interface is usually registered with a JNDI service provider. JNDI is used to provide a logical name to the DataSource object. A DataSource object can be created and managed using WebSphere. Some benefits when using JNDI include: The JDBC application that uses the DataSource object can refer to the object by its logical name, and does not need any information about the underlying data source. There is no need to modify the JDBC application if the data source attributes change.

5.2.3 Java identifiers and JDBC parameter markers


In general, applications that perform SELECT, UPDATE, INSERT, and DELETE operations require the ability to pass data between the user and the DBMS. Usually, the values being passed are unknown until run time. However, the data type of a particular value is known ahead of time. Mapping data types of these unknown values to the data type of a column in a database table is determined during the application planning and development stage. For example, whether a particular value is a character string or a numerical value is known during application programming. However, the actual value of the character string or number is not known until execution time. Within a JDBC application, it is possible to define an entity with a particular data type but without a specific value. In most programming languages, these are known as variables. In Java applications, they are called identifiers. Identifiers address the issue of variables within the JDBC application. However, UPDATE, INSERT, and DELETE operations often need to involve passing values in variables to DB2 tables. Java identifiers cannot be used in embedded SQL statements to accomplish this. Instead, another form of a variable called a parameter marker is used to represent input variables in SQL statements. Parameter markers are not defined in the JDBC application. A question mark (?) is used to represent a parameter marker in an SQL statement included in a JDBC application. Example 5-2 shows an UPDATE statement using parameter markers as the input values for the employee number (EMPNO) and phone number (PHONENO) when updating the employee (EMP) table. The parameter markers act as place holders for the input value in the SQL statement. The actual values for PHONENO and EMPNO are provided to the application at run time. The question marks are replaced with the values provided to complete a legitimate SQL statement. The SQL statement is then executed against the DBMS and the UPDATE statement is completed.
Example 5-2 UPDATE statement using parameter markers UPDATE EMP SET PHONENO=? WHERE EMPNO=?;

5.2.4 Statement and ResultSet interfaces


In a JDBC application, the Statement interface is used for executing SQL statements including SELECT, UPDATE, INSERT, and DELETE operations. When a Statement interface object is used to execute a SQL statement, the database result set returned by the SQL statement is retrieved using the ResultSet interface.

Statement interface
The Statement interface contains many methods. The most commonly use methods are: executeQuery() - Typically used to execute SELECT statements. This method returns a ResultSet object containing the database result set produced by the SQL query executed.

114

DB2 for z/OS and WebSphere: The Perfect Couple

executeUpdate() - Primarily used to execute INSERT, UPDATE, or DELETE statements. This method can also be used to execute DDL statements. A ResultSet object is not returned. close() - Although a Statement object is automatically closed during its garbage collection process, using this method to explicitly close the Statement object immediately releases database and JDBC resources held by the Statement object. A limitation of the Statement interface is that it can only work with fixed SQL. In other words, the actual SQL statement is hard-coded in the application, and does not use parameter markers. Even though the SQL statement itself does not change, being a JDBC application, the SQL statement is still treated under the dynamic SQL model at run time. With the DB2 Universal Driver, the Statement interface can be used to call stored procedures that do not have parameters. The PreparedStatement and CallableStatement interfaces are sub-interfaces of the Statement interface. Unlike the Statement interface, parameter markers can be used with these two interfaces. This functionality provides increased SQL statement flexibility within JDBC applications.

PreparedStatement interface
The PreparedStatement interface supports any SQL statement containing input parameter markers. The PreparedStatement interface can also be used for SQL statements with no parameter markers. With the DB2 Universal Driver, the PreparedStatement interface can be used to call stored procedures that have input parameters and no output parameters, and that do not return result sets. The the PreparedStatement interface: Provides the ability to precompile an SQL statement that will be issued quite often. Has performance advantages, because the statement is compiled and optimized only once. After syntax check, compilation, and optimization, a handle is returned to the JDBC driver. At the end of the program the statement handle is discarded.

CallableStatement interface
The CallableStatement interface also supports the invocation of a stored procedure. Stored procedures with input parameters, output parameters, or input and output parameters, or no parameters can be called with the CallableStatement interface. With the DB2 Universal JDBC Driver, you can also use the Statement interface to call stored procedures, but those stored procedures must have no parameters. For the JDBC/SQLJ Driver for OS/390, you must use the CallableStatement interface, even if the stored procedure has no parameters. Allow working with stored procedures that return output parameters. Centralize the business logic in terms of manageability and also in terms of running the query. Enforce uniformity across applications, as well as provide security to the database access. Last beyond the execution of the program. For the DB2 Legacy Driver, the CallableStatement interface must be used to call stored procedures even if the stored procedures do not have parameters.

Chapter 5. DB2 application development in a WebSphere environment

115

Callable statement considerations when using the Universal Driver can also be found on the following IBM Web site:
http://publib.boulder.ibm.com/infocenter/db2help/index.jsp?topic=/com.ibm.db2.udb.doc/ad /c0010281.htm

The considerations for callable statements are as follows when you use the DB2 Universal Driver: Uncatalogued stored procedures are not supported. CALL statements are only describable to DB2 UDB for Linux, UNIX, and Windows Version 8. If you will be accessing a back-level server, you must either set the input parameters or register the output parameters to the same data types that are declared for the underlying stored procedure. CALL parameters cannot be literals or expressions. If you are either querying data from callable statements or querying database metadata catalog information against DB2 for OS/390 and data retrieval is requested by column name (that is, methods such as ResultSet.getInt("columnName") are used), the DESCSTAT DSNZPARM needs be set to YES. If it is not, a -516 error will be returned. On DB2 UDB for OS/390 and z/OS Versions 6 and 7, two callable statements cannot keep their cursors open simultaneously against the same stored procedure.

ResultSet interface
The ResultSet interface provides access to the results that a query generates. The ResultSet interface has the same purpose as the cursor that is used in embedded SQL applications in other languages.

5.3 SQLJ application programming concepts


This sections primary focus is on SQLJ application development using the DB2 Universal Driver. 1.9, Using the DB2 Universal Driver for SQLJ and JDBC on page 26, provides information on how to install the DB2 Universal JDBC Driver. Detailed information on the installation process can be found in DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414, or Chapter 7, SQLJ tutorial and reference, of DB2 for z/OS and OS/390: Ready for Java, SG24-6435. For more details on SQLJ, see Chapter 7, SQLJ on page 139 of this publication.

Java packages for SQLJ


When coding SQLJ applications, packages that may need to be imported are: sqlj.runtime - SQLJ run-time API java.sql - Core JDBC API javax.sql - JDBC 2.0 standard extensions javax.naming - Classes and interfaces for Java Naming and Directory Interface (JNDI)

5.4 Preparing JDBC and SQLJ applications for execution


Before any Java application can run, just like with any other programming language, it must go through a preparation process. At a minimum, this usually involves compiling the application. This section describes the preparation process of JDBC applications and SQLJ applications.

116

DB2 for z/OS and WebSphere: The Perfect Couple

5.4.1 JDBC program preparation process


Java applications using only JDBC methods have a slightly easier program preparation process when compared to SQLJ. Exactly like preparing any other Java application, the program is compiled using the javac command. Unlike the traditional program preparation described in 1.6.2, DB2 packages, plans, collections, and package lists on page 17, for embedded SQL programming languages, there is no precompile or bind step in this case. Example 5-3 illustrates the syntax of compiling a Java application named DB2JavaSample.java (assuming you are in the directory in which the file resides). All JDBC applications normally run under the same (default) plan and set of packages that are bound as part of the JDBC installation procedure.
Example 5-3 Compiling a Java application javac DB2JavaSample.java

5.4.2 SQLJ program preparation process


In this section we describe the program preparation process for SQLJ programs. If you are familiar with the preparation process for embedded SQL in a language such as COBOL or C, you will see that the preparation process for SQLJ applications is quite similar. The program preparation process using the Legacy Driver and the Universal Driver is not the same. To give you a better understanding of the improvements when using the Universal Driver, we first introduce how the application preparation process works when using the Legacy JDBC Driver.

Using the Legacy JDBC Driver


In the past when the DB2 Universal JDBC Driver was not an option, preparing SQLJ applications using the DB2 Legacy JDBC Driver involved a three-step process, as illustrated in Figure 5-1 on page 118.

Chapter 5. DB2 application development in a WebSphere environment

117

SQLJ Source

SQLJ translator

Modified Source

(sqlj command)

Serialized profile

Customize
(db2profc command)

Customized Serialized profile

Compile
(javac command)

Four DBRMs

Java class file

BIND PACKAGE

BIND PLAN

Plan

Four Packages

Figure 5-1 SQLJ program preparation using the DB2 JDBC Legacy Driver

The process is: 1. Translate the SQLJ source code. The sqlj command can be invoked from the z/OS UNIX System Services command line, and is used to invoke the DB2 UDB for z/OS SQLJ translator. This step produces modified source code and one or more serialized profiles. The modified source code is then compiled using the javac command to generate a Java class file. Note: The available options and form of the sqlj command depend on the driver that you use. All forms of the sqlj command are documented in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414. 2. Customize the serialized profile using the db2profc command to produce standard DB2 for OS/390 and z/OS DBRMs. Although this is an optional step, it is highly recommended. If the serialized profiles are not customized, the SQLJ application will run under the dynamic SQL model, and not under the static SQL model. 3. Bind plans or packages.

Using Universal Driver


Applications using the DB2 Legacy JDBC Driver should, whenever possible, switch to using the DB2 Universal JDBC Driver. Besides the fact that the DB2 Universal JDBC Driver offers additional features and connectivity options, there is also one less step in the SQLJ program

118

DB2 for z/OS and WebSphere: The Perfect Couple

preparation process when using the Universal Driver. This is illustrated in Figure 5-2 on page 119.

SQLJ Source

SQLJ translator

Modified Source

(sqlj command)

Serialized profile

Customize
(db2sqljcustomize command)

Customized Serialized profile


Compile
(javac command)

Four packages Java class file

Figure 5-2 SQLJ program preparation process using the DB2 Universal JDBC Driver

SQLJ program preparation using the DB2 Universal JDBC Driver includes these steps: 1. Translate the source code using the SQLJ translator via the sqlj command. The result is modified Java source code (all SQLJ statements are now replaced with real Java statements) and one or more serialized profiles. The modified source code is then compiled using the javac command to generate a Java class file. Note: The available options and form of the sqlj command depend on the driver that you are using. All forms of the sqlj command are documented in the DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414. 2. Customize the serialized profiles using the db2sqljcustomize command to produce a customized serialized profile. When using the db2sqljcustomize command, you have the (default) option to produce DB2 packages at a specified data source. Note: When customizing a serialized profile, the customizer (db2profc or db2sqljcustomize) normally produces four packages for each serialized profileone for each isolation level (UR, CS, RS, and RR). More information about SQLJ profile customization using the Universal Driver can be found in 7.2, Profile customization on page 146.

Chapter 5. DB2 application development in a WebSphere environment

119

5.5 Impact of different DB2 bind options on Java applications


This section focuses on a subset of DB2 bind options that have the greatest impact on Java applications. The complete list of DB2 bind options and all their possible values is documented in DB2 Universal Database for z/OS Version 8 Command Reference, SC18-7416.

5.5.1 OWNER bind option


This option determines the authorization ID of the owner of the object (plan or package). The owner must have the privileges required to execute the SQL statements contained in the plan or package. For remote BIND or REBIND PACKAGE only, the value of OWNER is subject to translation when sent to the remote system. The default owner is the primary authorization ID of the agent that runs the bind process. The use of the OWNER keyword is important in SQLJ applications, as they adhere to the static authorization model. Packages are usually bound with an owner that has fairly high authorizations, as the execution of the plan or package really controls who can access the resources used in the plan or package.

5.5.2 QUALIFIER bind option


Determines the qualifier for unqualified names of tables, views, indexes, and aliases referenced in SQL statements contained in the plan or package. This value is not subject to translation when sent to a remote system for BIND or REBIND PACKAGE. If the QUALIFIER keyword is not specified, the owners authorization ID is used as the qualifier. It is recommended to use unqualified SQL statements, as it allows you more flexibility when deploying the application. Using unqualified SQL statements in combination with the QUALIFIER bind option allows you to easily switch to another set of tables without having to change any of the code inside the application.

5.5.3 DYNAMICRULES bind option


When dynamically executing an SQL statement, the authorization ID that is used to determine whether you are allowed to execute the SQL statement is determined by the DYNAMICRULES behavior that is in effect. The default is DYNAMICRULES(RUN). This means that the user who is executing the statement must have the authorization to perform the requested operation (SELECT, INSERT, UPDATE, or DELETE) on the requested object (table, view, etc.). When using SQLJ with the DB2 Universal Driver, the behavior is always DYNAMICRULES(BIND). This makes sense, as you normally want to use the static authorization model with SQLJ. You cannot modify this option. This option is mainly enforced to guarantee that positioned updates behave in an identical manner when executed as static SQL or as dynamic SQL. You control the way positioned updates and deletes are executed via the -staticpositioned option of the db2sqljcustomize and db2sqljbind commands. For iterators that are declared in the same source file as positioned UPDATE statements that use the iterators, it specifies whether the positioned UPDATEs are executed as statically bound

120

DB2 for z/OS and WebSphere: The Perfect Couple

statements. The default is NO. NO means that the positioned UPDATEs are executed as dynamically prepared statements. The DYNAMICRULES(BIND) option also causes the SET CURRENT SQLID statement to have no impact on a static SQLJ program, because those statements affect only dynamic statements that are bound with DYNAMICRULES values other than BIND.

5.5.4 ISOLATION bind option


This is discussed in more detail in Chapter 9, DB2 locking in a WebSphere environment on page 209.

5.6 Special registers


A special register is a storage area defined for a process by DB2. Wherever its name appears in an SQL statement, the name is replaced by the registers value when the statement is executed. Thus, the name acts like a function that has no arguments. We mention special registers here, as the value of some of them can be initialized by WebSphere at the Data Source level. This mean that when you connect to the Data Source with a certain name, the values associated with the custom properties of that Data Source will also be set, and amongst those are DB2 special registers.

5.6.1 CURRENT SQLID


The CURRENT SQLID can be initialized with a certain value when connecting to a Data Source. It is as if the application had executed a SET CURRENT SQLID statement in the program as the very first statement. A value for the CURRENT SQLID can be specified using the currentSQLID property of a data source. To do so, as always, we use the Admin Console. Data source properties can be specified via Resources JDBC Providers DB2 Universal JDBC Driver Provider Data Sources data-source-name Custom Properties. The configuration window is also shown in Figure 5-3 on page 122.

Chapter 5. DB2 application development in a WebSphere environment

121

Figure 5-3 Setting the currentSQLID property

5.6.2 CURRENT SCHEMA


The CURRENT SCHEMA special register is new in DB2 for z/OS Version 8. It can be set via the SET CURRENT SCHEMA or the SET SCHEMA SQL statement. For dynamic SQL in packages that use the DYNAMICRULES(RUN) option, it provides the same function as the QUALIFIER bind option for static SQL. It is used to qualify unqualified SQL for dynamic SQL (with DYNAMICRULES(RUN) behavior). The value you specify can be any value, unlike the CURRENT SQLID where you must specify a value that is your primary or a secondary authorization ID (unless you have some special administrative authorities like SYSADM). If the package is bound with the DYNAMICRULES BIND option, this statement does not affect the qualifier that is used for unqualified database object references. As far a Java applications are concerned, this option only affects JDBC applications and uncustomized SQLJ applications (but those should be the exception). They both run dynamic SQL. The CURRENT SCHEMA special register can be initialized with a certain value when connecting to a Data Source. It is as if the application had executed a SET SCHEMA statement in the program as the very first statement. A value for the CURRENT SCHEMA can be specified using the currentSchema property of a data source. To do so, as always, we use the Admin Console. Data source properties can be specified via Resources JDBC Providers DB2 Universal JDBC Driver Provider Data Sources data-source-name Custom Properties. The configuration window is also shown in Figure 5-4 on page 123.

122

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 5-4 Setting the currentSchema property

5.6.3 CURRENT PACKAGESET


The CURRENT PACKAGESET special register specifies a string of blanks, or the collection ID (only one) that will be searched to find the package that is used to execute SQL statements. The SET CURRENT PACKAGESET statement is used to specify the collection ID of a package that exists at the current server. The use of SET CURRENT PACKAGESET is optional. If the CURRENT PACKAGESET special register is an empty string, DB2 searches for a DBRM or a package using normal search order; DBRMs bound directly to the plan, already allocated packages, PKLIST, etc. If the special register CURRENT PACKAGESET is set, DB2 skips the check for programs that are part of the plan and uses the value of CURRENT PACKAGESET as the only collection to search for a package. For example, if CURRENT PACKAGESET contains COL5, and I am executing PROG1, then DB2 uses COL5.PROG1.timestamp for the search. The CURRENT PACKAGESET special register can be initialized with a certain value when connecting to a Data Source. It is as if the application had executed a SET CURRENT PACKAGESET statement in the program as the very first statement. A value for the CURRENT PACKAGESET special register can be specified using the currentPackageSet property of a data source. To do so, as always, we use the Admin Console. Data source properties can be specified via Resources JDBC Providers DB2 Universal JDBC Driver Provider Data Sources data-source-name Custom Properties. The configuration window is also shown in Figure 5-5 on page 124.

Chapter 5. DB2 application development in a WebSphere environment

123

Figure 5-5 Setting the currentPackageSet property

5.6.4 CURRENT PACKAGE PATH


Using the CURRENT PACKAGE PATH special register (new in DB2 for z/OS Version 8) is similar to using CURRENT PACKAGESET. However, CURRENT PACKAGE PATH allows you to specify a list of collections for DB2 to search in (instead of one as is the case for CURRENT PACKAGESET). It provides similar functionality as the PKLIST bind option. However, the CURRENT PACKAGE PATH special register can be set by the application. The CURRENT PACKAGE PATH special register can provide similar functionality as the PKLIST option for applications that do not run under a specific DB2 plan; for example, applications that come in through the network use the internal DISTSERV plan. This is especially interesting for SQLJ applications. It gives the application control over which DB2 collections to search. The value can also be set external to the application, when specified as a data source property, currentPackagePath, as shown in 5.6.5, Using properties to specify special registers on page 124. At the time of writing of this publication, WAS V5.02 and V5.102 did not yet support this option as a standard data source custom property. However, you can manually define currentPackagePath as a custom property using the Administrative Console. It will get passed to the datasource at execution time.

5.6.5 Using properties to specify special registers


Properties define how the connection to a particular data source should be made. The easiest way to specify those properties is via the WebSphere Administrative Console application as a (custom) property. In this section, we briefly describe other ways to set Universal Driver properties.

124

DB2 for z/OS and WebSphere: The Perfect Couple

Properties can be set in one of the following ways: Using setXXX methods - Properties are applicable to the following DB2-specific implementations that inherit from com.ibm.db2.jcc.DB2BaseDataSource: com.ibm.db2.jcc.DB2SimpleDataSource com.ibm.db2.jcc.DB2DataSource com.ibm.db2.jcc.DB2ConnectionPoolDataSource com.ibm.db2.jcc.DB2XADataSource

For example, to initialize the CURRENT PACKAGE PATH special register, you can set the currentPackagePath property by invoking the method:
DB2SimpleDataSource ds1=new DB2SimpleDataSource(); ds1.setCurrentPackagePath("myprivcol,devcol,prdcol");

Note: Notice that the property name is currentPackagePath (starting with lower case), whereas the set method uses an upper case setCurrentPackagePath. You can also specify properties when using DriverManager. On the DriverManager.getConnection call, you can specify a java.util.Properties value in the info parameter. In a java.lang.String value in the url parameter of a DriverManager.getConnection call. The last two options are merely mentioned for completeness, as we highly recommend the use of the DataSource interface over DriverManager. For a complete list of all properties supported by the DB2 Universal Driver, see DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

Chapter 5. DB2 application development in a WebSphere environment

125

126

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 6.

WebSphere - DB2 security


This chapter discusses authorization, auditing considerations, and configurations for WebSphere Application Server for z/OS (WAS) and DB2 UDB for z/OS (DB2). In this chapter, the following topics are discussed: Introduction to authentication, authorization, and auditing DB2 Authentication WebSphere Authentication configuration Auditing implementation

Copyright IBM Corp. 2005. All rights reserved.

127

6.1 Introduction to authentication, authorization, and auditing


These frequently incorrectly used terms represent three important attributes of a robust security infrastructure. Authentication, authorization, and auditing respectively describe mechanisms for verifying a requestors identity, determining that users access to resources, and recording all actions taken by a user.

6.1.1 Authentication
There are multiple mechanisms for validating the identity of a requestor. The most common implementation is to challenge the requestor for a user ID and password. The user ID and password are static entities that generally do not change for an extended period of time, although some security policies can enforce a relatively frequent password change. The major drawback of such an approach is that if a users user ID and password are compromised, other users can easily assume their identity. For non-encrypted user IDs and passwords that flow across a TCP/IP network, it is relatively easy to sniff the user ID and password. There are implementations of authentication other then user ID and password challenges. A less secure approach is simply a user ID without the requirement for a password. A more secure approach includes authentication standards such as Kerberos. In Kerberos implementations, a third-part authentication server in conjunction with public and private keys and a timestamp are able to allow a requester and server to verify each others identity. The important notion about Kerberos is that the tokens used to authenticate a user are not static. Each time an exchange is created the actual credentials exchanged are based upon a number of public and private keys and a timestamp. That means that even if the security ticket was intercepted, it would be extremely difficult to derive value out of it. The details are beyond the scope this book since, even though the DB2 JDBC driver and DB2 for z/OS support Kerberos, WebSphere currently does not exploit this function. The important notion in Kerberos is that a security token is generated for each request using a combination of algorithms against private and public keys.

6.1.2 Authorization
Authorization is the process of controlling access to resources based upon the authentication of an end user. As part of the system, a security policy dictates what resources a specific identity can access and what type of access is allowed. For example, in a relational database, an authenticated end user must be authorized to access a table for the intended action (select, insert, update, delete). If the user is only authorized to read a table, attempts to insert, update, or delete will be denied, but attempts to select will be permitted.

6.1.3 Auditing
Auditing is the process of recording actions taken by users. This includes actions that are both permitted and denied. A good auditing implementation will allow review of all actions by end users. Not only are the actions recorded, but the service that authenticated the user and allowed or denied the user authorization to access a resource must all be recorded. Auditing logs must also be blocked from update by users of system. The ability to remove an auditing entry would invalidate the benefit of the auditing system.

128

DB2 for z/OS and WebSphere: The Perfect Couple

6.1.4 Application or infrastructure


In general, authentication, authorization, and auditing should not be a function of an application. These security features should be implemented for every application regardless of which platform or language the applications execute within. Applications tend to consider function and performance a premium; security is generally an after thought. Whether unintended or malicious, application developers are prone to making security implementation mistakes or implementing security with different mechanisms in each application, making security management a nightmare. Alternatively, authentication, authorization, and auditing should be implemented as part of the infrastructure and with as little infrastructure as possible.

6.1.5 DB2-supported authentication, authorization, and auditing


In this section we discuss DB2-supported authentication, authorization, and auditing.

DB2 JDBC authentication


For JDBC applications, there are multiple choices for authenticating an end user. These options are dependent upon the connection mechanism, either type 2 or type 4. The options allow DB2 to either inherit the previously authenticated RACF user ID of the process connecting to DB2, allow the connecting thread to specify only a user ID, or specify a user ID and password.

DB2 Universal type 4 Driver authentication


For remote requests, a combination of settings at the type 4 JDBC Driver and the DB2 for z/OS servers Distributed Data Facility determine the types of authentication that are supported. You choose which type of authentication to use when attempting to connect from the JDBC client via a property of the datasource. The property, securityMechanism, determines security attributes for transmitting data in addition to determining the requirements for authentication. Here are the supported types for the JDBC drivers securityMechanism property, which is of type integer: CLEAR_TEXT_PASSWORD_SECURITY (3): In this case the user ID and password are required to be sent to the server for authentication, and the fields are passed through the network in clear text. Only the user ID is required to be sent to the server. This value requires that the servers TCPALVER ZPARM must be set to YES (a setting generally discouraged since this results in no password challenge). User ID and password are required to be sent to the server for authentication. The password is sent encrypted and is not in plain text across the network.
Chapter 6. WebSphere - DB2 security

USERID_ONLY_SECURITY (4):

ENCRYPTED_PASSWORD_SECURITY (7):

129

ENCRYPTED_USER_AND_PASSWORD_SECURITY (9): User IDs and passwords are required and are encrypted when sent on the network. ENCRYPTED _USER_AND _DATA_SECURITY(12): The user ID and password are required for authentication, the user ID and data are sent encrypted, and the password is sent in clear text. User ID and password are required and encrypted; data is encrypted as well. Kerberos infrastructure is exploited; no user IDs or passwords are sent. Note that this is not supported within a WebSphere environment.

ENCRYPTED_USER_PASSWORD_AND _DATA (13):

KERBEROS_SECURITY (11):

If a user ID and password are specified, DB2 issues a Security Access Facility (SAF) check to verify that the user ID and password are valid. Once the thread is successfully authenticated, the user executes with the authorization of the specified user ID and password. The AUTHID is then associated with the thread within DB2. To exploit the user ID only mechanism, the TCPALVER DSNZPARM at the server must be set to YES. Please note that setting this parameter to yes is strongly discouraged and is analogous to giving away all of the data within the database. A user would only need to know a valid user ID to get access to a system. According to the Java programming guide, if you do not specify a value for this property, the most secure mechanism supported by the server is attempted. However, in our testing we found that not specifying a value within WebSphere resulted in the use of user ID and password in clear text.

DB2 Universal type 2 Driver authentication


For type 2 connections, a connection can be created using a specific authentication by specifying a user ID and password. If a user ID and password are specified, DB2 verifies the values by issuing a SAF call to RACF. If successful, the thread then carries the security context of the authorization ID and DB2 associates the thread with the AUTHID while performing actions within DB2. Alternatively, the thread can connect to DB2 without specifying a user ID and password. When this occurs, the thread will assume the security contexts of the process, which is connecting to DB2.

6.1.6 Choosing what identity to send DB2


While there are multiple other permutations of providing authentication, there are three general accepted approaches to authenticating when connecting from WebSphere to DB2: Programmatic specification of a user ID and password within the application, using a default user ID and password within the datasource definition, or allowing the system to challenge an end user for user ID/password and then propagating that ID through to your DB2 connection without programmatic action. This last option, known as thread identity support, is only supported with the type 2 connectivity on z/OS.

130

DB2 for z/OS and WebSphere: The Perfect Couple

While we generally agree it is a good idea to have an end users identity flow with a user all the way through the transaction and through the datastore, there are multiple issues in a WebSphere environment that prohibit this propagation of authorization.

Performance
The connection pooling function, probably the most important optimization for performance within the datasource, allows connections to be repeatedly reused without the need to establish a new connection, which is expensive. Unfortunately, in WebSphere Version 5, the connection pooling is organized and maintained by authorization ID. Connections or applications that want to use unique authorization IDs cannot share connections or benefit from connection pooling.

No thread identity support in type 4 connectivity


The only way to propagate the end users identity without moving the end users ID and password through the application, which is also a poor choice from a security standpoint, is to exploit thread identity support. Unfortunately, in a distributed environment, the remote DB2 server cannot inherit the calling threads security attributes through the type 4 JDBC driver.

Too many Web users


In a large Internet environment, setting up as many RACF entries (one for every potential end user) can be cumbersome and negatively impact normal operation of the system.

Choosing the authentication approach


As a result, the most common choice is to choose a default user ID and password for the datasource. This does cause an issue for identifying individual end users or transactions, since each of the transactions acts against DB2 with the same authorization ID.

6.1.7 Configuring WebSphere for authentication


Since the focus of this book is the interaction between WebSphere and DB2, many of the security features available within WebSphere are out of the scope of this document. WebSphere provides robust security management including authentication, authorization, and auditing infrastructure for WebSphere-based applications. These facilities interact with the zSeries Security Server (or equivalent) to augment the security infrastructure provided directly within WebSphere. Configurations within the Enterprise JavaBean, with the global security settings, and within the datasource definition all affect how the identity is determined for accessing DB2.

Setting the JDBC driver securityMechanism


To set the securityMechanism value within WebSphere, a property must be added to the custom properties of the datasource. As shown in figure Figure 6-1 on page 132, the property is added as an integer field and can be set to the values described in DB2 JDBC authentication on page 129.

Chapter 6. WebSphere - DB2 security

131

Figure 6-1 Adding the securityMechanism property

Deployment descriptor settings (EJB configuration)


When deploying a Bean into WebSphere, deployment descriptors determine how the identity might be determined. The Run-As attribute determines how the server should choose the identity to attempt to execute a Bean, which ultimately can affect the identity that is propagated to DB2. This attribute, Run-As, gives the EJB container instructions on which methodology to use for choosing an execution identity. The container supports two mechanisms, as described in the EJB specification Run-As=caller, where the Bean inherits the identity of the caller. Alternatively, the Run-As=role option tells the container to execute the Bean using the defining identity. In addition, as an IBM extension to the specification, a Run-As=server option allows the Bean to execute with the identity of the EJB container. Within the WSAD environment, a deployment descriptor for each of the Beans determines the Run-As value. You can specify this value either at the Bean level or at the method level, as shown in figure Figure 6-2 on page 133.

132

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 6-2 Specifying a Beans Run-As value

In addition to the Run-As attribute, the Res-Auth deployment descriptor within the WSAD environment indicates who should be attempting to provide the identity, the application or the container. This attribute lets the container know if the application plans on providing a programmatic user ID and password. Res-Auth, which is short for Resource Authentication, can be set to either container or application. The value is set within the deployment descriptors reference to the datasource. This same window also sets the isolation level for the datasource, as discussed in 9.3.1, Setting the WebSphere transaction isolation level on page 217. Figure 6-3 on page 134 shows the res-auth value being set within the deployment descriptors reference for a datasource.

Chapter 6. WebSphere - DB2 security

133

Figure 6-3 Setting the Res-Auth value within an EJB reference to a datasource

WebSphere datasource settings for authentication


Within the WebSphere datasource definition, there are two potential fields for specifying the identity to be utilized. Since the datasource can be referenced by an application wanting to have the container determine the identity, or allow the program to specify the user ID and password for connectivity, the datasource definition supports the setting of an authorization ID in the datasource definition. The potential authentication values themselves are defined within the Security JAAS Configuration JCA Authentication option of the administration console application. Figure 6-4 shows the specification of a user ID and password.

Figure 6-4 Setting JCA user identity and password

134

DB2 for z/OS and WebSphere: The Perfect Couple

The user ID and password must be a valid SAF user ID, if they are to be used for connectivity to DB2 and referenced in the datasource definition. Once the JCA authorization IDs are defined, the datasource can specify an ID to be used if the datasource is accessed with res-auth=container, and a separate ID if res-auth=application is used. Figure 6-5 displays how to set the value. Component-managed aliases are used for res-auth=application, and container-managed aliases are used for res-auth=container.

Figure 6-5 Setting the container and component JCA identities

6.1.8 Programmatic authentication


To configure an application to use a programmatic, application-based user ID and password, the application must be deployed with Res-auth=application, and no value can be specified in the datasource field for Component-managed Authentication Alias. If a value is present in the component-managed authentication alias, user ID and password values specified in the application will be ignored (see Figure 6-5).

6.1.9 Default user ID and password authentication


To specify a default user ID and password, the Res-auth should be set to container, and a value for container-managed authentication alias should be specified.

6.1.10 Thread identity support


To allow a threads identity to flow through to DB2 without specifying a new one, there are global security requirements in addition to the configuration mentioned above. First, global security must be enabled, which is turned on via a check box within the Security Global security tab of the Administrative Console. More information should be gathered from the WebSphere manual regarding this option, as enabling global security will have a large impact on the management of your system.

Chapter 6. WebSphere - DB2 security

135

Once global security is enabled, the application also requires that Sync to OS Thread is enabled for the server. Within the Security Global security z/OS Security options tab of the Administrative Console, the option to allow sync to os can be enabled by flagging the check box, as shown in Figure 6-6.

Figure 6-6 Enabling Sync To OS thread support

For your application, Run-As caller should be set for the Bean in the deployment descriptor; and within the reference to the datasource, resauth should be set to container; and no value for container-managed alias should be specified in the datasource definition.

6.2 DB2 auditing


If we make the assumption that the security mechanism for authentication will result in all of the users for an application exploiting the same user ID and password, the ability for the application to perform auditing tasks is significantly reduced. To help with this issue, DB2 provides client strings that can be set by the application, which can help applications provide specific end user information to the client. An application may choose to set these fields to the end user of the application if the data was propagated back to the data access portion of the application. The client strings are actually four different strings that can be set to any value of your choosing. The value of these strings shows up in the output of the -DISPLAY THREAD command and DB2 trace records. Those can be processed by batch reporting tools or online monitoring tools such as DB2 Performance Expert. For batch reporting, three of the fields are included in the standard header for SMF data (see Table 6-1). This means that DB2 reports can be filtered or ordered by for these reports. Refer to your batch reporting users guide for more information on how to generate reports including these strings, or how to limit results to a specific value. For example, DB2 Performance Expert statistics, accounting, and audit reports can all be created based upon these fields.
Table 6-1 Client accounting strings String ClientWorkstation ClientUser ClientProgramName Maximum length 18 16 12 In standard header YES YES YES

136

DB2 for z/OS and WebSphere: The Perfect Couple

String ClientAccountingInformation

Maximum length 22

In standard header NO

Setting the client strings


While currently under development for a future release, there is no standardized, easy-to-use mechanism for setting these client strings within an application running inside WebSphere Application Server. Since within WebSphere you cannot actually reference the underlying vendor-specific interfaces, WebSphere provides a pass-through mechanism that is slightly cumbersome to exploit. More information on this function is provided in the WebSphere Technical support document number 1142347, which can be found via a search at: http://www.ibm.com/software/webservers/appserv/was/support/ Example 6-1 shows a code sample for setting these client strings using the information contained in the Tech doc. After importing a WebSphere class, com.ibm.websphere.rsadapter.WSCallHelper, and creating a Connection con, the following methods are available.
Example 6-1 Setting the workstation client strings public void setWorkStationName(Connection con, String work) throws SQLException,Exception { WSCallHelper.jdbcCall(null,con,"setDB2ClientWorkstation",new Object[]{new String(work)}, new Class[] {String.class});} public void setApplicationName(Connection con, String appl) throws SQLException,Exception { WSCallHelper.jdbcCall(null,con,"setDB2ClientApplicationInformation",new Object[]{new String(appl)}, new Class[] {String.class});} public void setAccounting(Connection con, String accounting) throws SQLException,Exception { WSCallHelper.jdbcCall(null,con,"setDB2ClientAccountingInformation",new Object[]{new String(accounting)}, new Class[] {String.class}); } public void setEndUser(Connection con, String endUser) throws SQLException,Exception { WSCallHelper.jdbcCall(null,con,"setDB2ClientUser",new Object[]{new String(endUser)}, new Class[] {String.class}); }

Note that if any applications set these fields, the values will not be reset when returned to the connection pool. Applications must all set these values at the beginning of the transaction to correctly collect and report data based upon these fields. As mentioned above, the upcoming version of WebSphere Application Server will make it easier to set the DB2 client strings. The plan is to allow you to wrap the Connection with a WSConnection class (com.ibm.websphere.rsadapter.WSConnection). This interface provides a number of methods, such as setClientInformation, getClientInformation (and getSystemMonitor). This API allows you to set client information on the WebSphere connection. Some of the client information will be passed on to the back-end database, if the database supports such functionality (which is the case for DB2). A simplified code snippet is shown in Example 6-2. The only intention is to demonstrate how much easier it will become to set the client strings in a WAS environment in the near future.
Example 6-2 WSConnection using setClientInformation method import com.ibm.websphere.rsadapter.WSConnection; .....

Chapter 6. WebSphere - DB2 security

137

try { InitialContext ctx = new InitialContext(); // Perform a naming service lookup to get the DataSource object. DataSource ds = (javax.sql.DataSource)ctx.lookup("java:comp/jdbc/myDS"); } catch (Exception e) {;} WSConnection conn = (WSConnection) ds.getConnection(); Properties props = new properties(); props.setProperty(WSConnection.CLIENT_ID, "user123"); props.setProperty(WSConnection.CLIENT_ACCOUNTING_INFO , "accounting1"); props.setProperty(WSConnection.CLIENT_APPLICATION_NAME, "appname"); ... conn.setClientInformation(props); conn.close();

The example shows that you do not use a DB2Connection object to set the client strings in a WAS environment, but use WSConnection instead.

138

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 7.

SQLJ
This chapter describes the use of embedded SQL in Java, also known as SQLJ. We also compare SQLJ to JDBC, that is, dynamic SQL in Java applications. Next, we look at how to write an application using SQLJ in a WebSphere Application Server environment, and how to use SQLJ with WebSphere Studio Application Developer. This chapter contains the following topics: Writing SQLJ versus JDBC applications Profile customization Application design SQLJ in WebSphere Studio Application Developer

Copyright IBM Corp. 2005. All rights reserved.

139

7.1 Writing SQLJ versus JDBC applications


SQLJ and JDBC basically solve the same problem, which is to execute SQL statements against a database. The major difference between Java programs using JDBC and SQLJ programs, from a development point of view, is that SQLJ programs have to be preprocessed prior to execution. This is due the way SQL statements are coded in SQLJ programs. Unlike JDBC, which is a call-level interface (an API) like ODBC, SQLJ is a language extension. When an SQLJ program has been coded, it is first run through the SQLJ translator, fittingly called sqlj. This takes the SQLJ statements and replaces them with valid Java methods. The SQL statements are placed in a file named ClassName_SJProfile0.ser while the Java code is placed in a standard Java file called ClassName.java. The program file can now be compiled using a standard Java compiler (javac), and run. (The sqlj translator compiles the program automatically, unless you use a command line switch (-compile=false) to suppress it.) Besides the mandatory translation step, we can (and should) also execute an optional customization step. Not all DBMS systems supporting SQLJ also support customization, but DB2 does. During customization (against a DB2 system), the SQL statements in the .ser files are bound into packages, and they will execute as true static SQL statements at run time. In case the DBMS does not support customization, or customization has not been done, the translated SQLJ statements are executed through JDBC as dynamic SQL. A more general discussion comparing SQLJ and JDBC can be found in Figure 5.1 on page 110.

7.1.1 Connections
Before we can execute any SQL statements against a DBMS, we need a connection. Though written in different ways, getting a connection from SQLJ is identical to getting a connection from JDBC. In fact, SQLJ uses JDBC to retrieve a connection. Two different methods can be used to obtain a connection to a DBMS in Java: The DriverManager interface The DataSource interface When using the DriverManager interface, the names of both the driver and the database are coded directly into the method calls within the application code. Using a DataSource object instead of DriverManager removes this direct coding of driver and database names from the application. This information is kept and maintained separately, for instance, in WebSphere Application Server. The data source is then retrieved by a lookup with a logical name known to the application. Important: When accessing DB2 from WebSphere Application Server, we always use the DataSource interface. One of the reasons is that we get connection pooling with the DataSource interface. The result is better scalability and more robust applications. In this book we concentrate entirely on using the DataSource interface. If you are interested in the DriverManager interface, please refer to DB2 for z/OS and OS/390: Ready for Java, SG242-6425, as well as DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

140

DB2 for z/OS and WebSphere: The Perfect Couple

DataSource versus datasource In this section we use the terms DataSource and datasource, but even though they are
spelled the same, they are different things, which is of course a little confusing. The

datasource we define within WebSphere Application Server, and it represents a connection to


a database. The DataSource (or DataSource interface) is the Java class we use to get access to the datasource.

Connecting using the DataSource interface


As mentioned above, SQLJ uses JDBC connections under the covers when we use a DataSource to get connections. The DataSource is a persistent object, and once created it is maintained as a system object, and is brought into the application referring to the logical name. The beauty of this setup is that we can have the same datasource name, defined on different platforms, and on each platform it contains platform-specific information. This makes the application far easier to deploy on different platforms. Another benefit is that we can have the same datasource name point to different databases at different times, or on different platforms, without changing the application. The datasource is defined and managed within the WebSphere Application Server, that also assigns a logical name to it through the Java Naming and Directory Interface (JNDI). The application using the datasource only refers to it by the logical name, knowing nothing about the actual DBMS. This implies, furthermore, that the system administrator can change the attributes of the datasource, without the application knowing or caring about it. Note: Refer to Chapter 3, WebSphere - DB2 environment on page 49, for setting up a datasource in WebSphere Application Server; and to 7.4.2, Create the server and the datasource on page 161, for setting up a datasource in WebSphere Studio Application Developer.

Getting a connection in JDBC


As mentioned earlier, we use the Java Naming and Directory Interface (JNDI) to look up the datasource. To access information in JNDI, we use the Java class InitialContext. We can use this class to retrieve objects stored in the JNDI by referencing the objects logical name. Through the InitialContext, we look up the datasource, and it will return a DataSource object to us. Through the DataSource object we get a connection. The simplest way to do all this is shown in Example 7-1. In this example we do not specify any user ID or password to the getConnection method. In that case, the connection is created with the default user. On WAS z/OS, the default user is stored in the server itself.
Example 7-1 Look up of the datasource using default values import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.Connection; InitialContext context = new InitialContext(); DataSource ds = (DataSource) context.lookup(jdbc/ITSO1); Connection conn = ds.getConnection();

In the above example, the InitialContext loads the object stored in JNDI on the server where it is instantiated. That is a local look up. We actually have the opportunity to look up objects that live in the JNDI on any server. To do this, we initialize the InitialContext class with a set of properties that tells the InitialContext which server to use. This is shown in Example 7-2 on page 142. In this example we explicitly specify the user ID and password as well.

Chapter 7. SQLJ

141

Example 7-2 Look up of the datasource in detail import import import import import javax.naming.InitialContext; javax.naming.Context; javax.sql.DataSource; java.sql.Connection; java.util.Properties;

Properties prop = new Properties(); // #1 properties.put( Context.PROVIDER_URL, iiop://hostname:portnumber); // #2 properties.put( Context.INITAL_CONTEXT_FACTORY, com.ibm.websphere.naming.WsnInitialContextFactory); InitialContext context = new InitialContext( properties); // #3 DataSource ds = (DataSource) context.lookup(jdbc/ITSO); Connection conn = ds.getConnection( userId, password);

If the object we are looking for lives on another server, we can tell the InitialContext which server to use by adding a PROVIDER_URL, as shown. Your system administrator can supply you with the information about the hostname and the portnumber. When we specify the PROVIDER_URL, we also need to specify the Java class that is doing the job on the server specified. This is done by specifying the INITIAL_CONTEXT_FACTORY. The one used by WebSphere Application Server is shown in the example. Now the InitialContext has the information to look up the DataSource, and we get the connection with a specific user ID and password. Tip: Lookup through the Java Naming and Directory Interface (JNDI) is fairly costly. That is why we only want to do the lookup once, and keep the reference in a cache. This cache is usually implemented as a static Java class using a hash-table. Example 7-3 is without error handling, but shows the concept. See itso.sqlj.servlet.HomeFactory in the sample application for a complete implementation.
Example 7-3 Caching the lookup information public class MyCache { private static MyCache cvSingleton = new MyCache(); private Hashtable ivCache = new Hashtable(); private HomeFactory() { // Load the datasources into the cache InitialContext initialContext = new InitialContext(); ivCache.put("jdbc/ITSO1", initialContext.lookup("jdbc/ITSO1"); ivCache.put("jdbc/ITSO2", initialContext.lookup("jdbc/ITSO2"); } public static final MyCache getInstance() { return cvSingleton; } public Object getDataSource( String jndiName) { return ivCache.get( jndiName);

142

DB2 for z/OS and WebSphere: The Perfect Couple

} }

Getting a connection in SQLJ


As SQLJ uses JDBC to get the connection, the approach is very similar to JDBC. The difference is that the connection is wrapped in a class called the connection contextor just the context. We do not create the connection context class ourself; this is done by the SQLJ preprocessor. We only have to define it, as shown in Example 7-4.
Example 7-4 Getting a connection in SQLJ import javax.naming.InitialContext; import javax.sql.DataSource; import java.sql.Connection; // step 1: #sql static context MyConnectionContext; // step 2 : InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(jdbc/ITSO1); Connection conn = ds.getConnection(); // step 3 : MyConnectionContext myContext = new MyConnectionContext(conn);

The steps are: 1. This is where we define the context class. The name after the reserved word context must be a valid Java class name. 2. This is where we create the connection. This step is identical to the JDBC approach. We can set additional attributes on the connection in this step as well, for instance, setting the autocommit feature to false. As with JDBC, we can choose to retrieve the connection with or without specifying a user ID and password. 3. Finally, we create an instance of the context class. Notice that the connection we created in step 2 is passed as a parameter to the constructor of the context class. With the DB2 Universal Driver, we have a simpler way to create the connection context. We can add a with-clause to the context definition, as shown in Example 7-5. Here we specify the datasource directly, so we do not need to manually create a connection. Note that step 2 is obsolete in this case. If we need to supply the user ID and password, we give them as parameters to the constructor of the context class.
Example 7-5 Creating the context using Universal Driver features // step 1 : #sql public static context MyConnectionContext with (dataSource=jdbc/ITSO1); // step 3a: MyConnectionContext myContext = new MyConnectionContext(); // step 3b: if we want to specify userid and password, we use MyConnectionContext myContext = new MyConnectionContext( userid, password);

Tip: The context class simply wraps the connection, and if we need to get hold of it, we simply call getConnection() on the context class. We can, for instance, disable the autocommit feature by calling myContext.getConnection().setAutoCommit(false);

Chapter 7. SQLJ

143

For more information about setting additional attributes on the connection context, refer to Chapter 3 of DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

Connections and transactions


Connections and transactions are highly interrelated. We have to handle the connection differently, whether we are using it within the scope of a transaction or not. When it comes to J2EE, we are usually using the connection in a Web container or in an EJB container. In a Web container there is no transaction by default, so we must handle the connection ourself. This can be done by either creating a user transaction, or by controlling commit, rollback, and so on ourselves. In an EJB container, we are always within the scope of a global transaction, leaving the management of the connection to the Transaction Manager. Later in this chapter we look at some examples of how to handle the connection in the different types of container.

7.1.2 Using SQLJ


There are four different forms of SQLJ statements: Connection contexts Executable statements Assignment statements Iterator declarations Common for all SQLJ statements is that they start with the token #sql and end with a semicolon (;). We have already seen the first one, namely creating the context. We now look briefly at the executable statement, which is the simplest SQLJ construct. You use an executable statement to perform database operations such as: Selecting, inserting, modifying, and deleting data Creating database objects Controlling transactions (commit and rollback) Calling stored procedures We take a closer look at the executable statement. It can appear anywhere a Java statement can appear, and it looks like this:
#sql [context] { SQL-statement};

Important: Even though the context is optional, we highly recommend that you specify it. If the context is not specified, an implicit context is created, namely the default context. The default context is a static variable and therefore shared by every thread in the same JVM. This can lead to a throughput bottleneck, but worse, another thread can change the default context while we are using it. Conclusion: We always use a specific context. Let us now have a look at the employee table in the sample database that comes with DB2. A subset of the columns is shown in Table 7-1.
Table 7-1 Subset of columns in the employee table from the DB2 sample database Column name EMPNO Description Employee number (the primary key)

144

DB2 for z/OS and WebSphere: The Perfect Couple

Column name FIRSTNME LASTNAME HIREDATE SALARY

Description First name of the employee Last name of the employee Date of hire Yearly salary in dollars

We want to retrieve these columns into a Java application for the employee with the EMPNO equal to 000130. Apart from creating the connection context, we need to define some host variables that we can select the values into. With the context at hand, along with the host variables, we are ready to write our SELECT statement, as shown in Example 7-6.
Example 7-6 Writing a SELECT statement using SQLJ String empno= 000130; // Define the connection context #sql public static context MyContext with (dataSource=jdbc/ITSO1); // Host variables to select into String firstname = null; String lastname = null; java.sql.Date hiredate = null; java.math.BigDecimal salary = null; // Create an instance of the context class MyContext context = new MyContext(); // The SQLJ Select statement #sql [context] { SELECT FIRSTNME, LASTNAME, HIREDATE, SALARY INTO :firstname, :lastname, :hiredate, :salary FROM EMP WHERE EMPNO = :empno } // Tell the Transaction Manager that we are done with the connection for now context.close();

Assuming we are running within the scope of a transaction in WebSphere Application Server, closing the context will not close the underlying connection. We just put the connection in a valid state for commit, leaving to the Transaction Manager to commit, or rollback, when appropriate. In 7.3, Application design on page 150, we discuss in more detail how to handle the connection from different parts of a J2EE application. The SQL statement can be almost any DB2 statement that can be statically prepared. Additionally, there is a special statement to set the isolation level for the current transaction:
#sql [context] { SET TRANSACTION ISOLATION LEVEL level};

Where level is one of values the listed values in Table 7-2. Please be aware that both JDBC/SQLJ and DB2 use the term repeatable read, but for different purposes.
Table 7-2 SQLJ isolation levels and their corresponding DB2 counterparts SQLJ isolation level READ UNCOMMITTED DB2 isolation level UR (uncommitted read)

Chapter 7. SQLJ

145

SQLJ isolation level READ COMMITTED REPEATABLE READ SERIALIZABLE

DB2 isolation level CS (cursor stability) RS (read stability) RR (repeatable read)

For further information about the SQLJ language, refer to DB2 for z/OS and OS/390: Ready for Java, SG24-6435. Important: SQLJ only runs as static SQL when it has been customized. Uncustomized SQLJ runs as JDBC and dynamic SQL under the covers. So uncustomized SQLJ is potentially slower than JDBC, due to the overhead of the SQLJ run-time library. More information about profile customization can be found in 7.2, Profile customization on page 146.

7.1.3 Using JDBC


There are situations where SQLJ cannot be used, for instance, if the user has the ability to build dynamic queries online. This leaves SQLJ in a somewhat troublesome situation, but this is not a problem, as SQLJ and JDBC are 100 percent interoperable. They can share the same connection, and SQLJ provides constructs to convert a JDBC result set into a SQLJ iterator, and vice versa. This makes it possible to construct and execute a query dynamically using JDBC operations, and evaluate the queries result set using SQLJ syntax. To convert a JDBC result set into a SQLJ iterator, you use the CAST construct (also known as the iterator conversion statement):
#sql iter = { CAST :resultset}

In the statement above, iter is an instance of a public SQLJ iterator class, and resultset is a JDBC ResultSet object. The other way around is possible as well, but not recommended, as the result is implementation defined, which is another way of saying that it may or may not work as you expect. However, it does work with the DB2 Universal Driver. To convert an SQLJ iterator into a JDBC result set, use the getResultSet method on the iterator class.
ResultSet rs= iter.getResultSet();

7.2 Profile customization


After the (mandatory) translation of your SQLJ program, to convert the SQLJ statements into pure Java code, you can and should customize your serialized profiles (.ser files) produced by the translation step. Not all DBMS systems supporting SQLJ also support customization, but DB2 does and customization provides a major advantage for DB2, compared to other DBMSs. During customization against a DB2 system, the SQL statements in the .ser files are bound into packages, and they will execute as true static SQL statements at run time. In case the DBMS does not support customization, or customization has not been done, the translated SQLJ statements are executed through JDBC as dynamic SQL.

146

DB2 for z/OS and WebSphere: The Perfect Couple

Important: The real strengths of SQLJ come only into play through the customization process. Do not expect better performance of SQLJ programs over equivalent JDBC programs if no customization has taken place. In fact, uncustomized SQLJ will rather run slightly slower because of some additional overhead in the SQLJ run time. The profile customizer for the DB2 Universal Driver (db2sqljcustomize) adds customization information to each entry in the profile. As mentioned before, this customization information is DBMS specific, and additional program preparation steps may be necessary before the customized program can successfully be run against the database. In the case of DB2, during profile customization, a DB2 package is created in the database catalog (actually, four packages by default, one for each isolation level). The serialized profile is also updated by the customization process. The DB2 customization information includes the package name (supplied when invoking the profile customizer command); a timestamp indicating when the customization took place; and a consistency token, used to ensure that the database package matches the profile. When an SQLJ implementation reads a serialized profile at run time, it checks for available customizations that are compatible with that particular implementation. When no such customization is found, the SQLJ run time falls back to using dynamic SQL; that is, it reads the actual SQL text of the statements, and prepares and executes these statements dynamically using JDBC calls. This is in fact one of the beauties of SQLJ, as opposed to other languages with embedded SQL support. Whereas in COBOL, for example, you are required to bind your program against the database after translationotherwise, you get a run-time error when executing itthis is not the case with SQLJ. Rather, you simply translate the program and the SQLJ run time will figure out whether the program has been customized. This is very convenient during program development, since you can omit the customization (and bind) step until your program is ready for deployment. Important: However, if the profile has been customized for DB2 (customization information present in the serialized profile), and for some reason the package has not been bound against the database during (or after) customization, you receive a -805 SQL error (package not found) at run time. You will also receive this error when the package had been bound before, but the SQLJ file was retranslated and re-customized without rebinding the package. In this case, the consistency token recorded in the profile does not match the one in the database. So once the profile has been customized for DB2, you must have a matching package bound in the database. In this case, SQLJ run time will not revert to using JDBC. When using the customizer provided with the DB2 Universal Driver, the profiles remain platform independent, even after customization, because SQLJ implementations are required to ignore customization information they do not know about. (This is not the case when using the customizer provided with the DB2 Legacy Driver (db2profc).) In fact, it is possible to customize one profile several times, once for each target database system. This makes it possible to run the program unchanged against, say, DB2 and Oracle databases. However, all DB2 implementations across the DB2 family use the same customization. You do not have to customize again when switching from a DB2 for Linux, Unix, and Windows to DB2 for z/OS and OS/390 when using the DB2 Universal Driver.

Chapter 7. SQLJ

147

As mentioned before, by default, db2sqljcustomize automatically binds the DB2 packages. You can use it an option to disable automatic creation of packages during customization. You need to specify the -automaticbind NO parameter in that case. This is shown in Example 7-7 with a serialized profile called Test_SJProfile0.ser.
Example 7-7 Disable automatic creation of DB2 packages during customization db2sqljcustomize -automaticbind NO Test_SJProfile0.ser

If the packages are not bound during customization, you can use the db2sqljbind utility to bind packages at a later time. Java applications that use the DB2 Universal Driver require packages but no plans. The DB2 packages are bound at the data source (DB2 system) that you specify in the -url parameter (of the db2sqljbind or db2sqljcustomize command). The -url parameter is always a hostname:portnumber combination. This means that even when binding against a (local) DB2 system on the same z/OS, you use a remote bind (and access that DB2 via DDF.) This implies that you must have DDF set up and active before you can start using the DB2 Universal Driver. Important: DDF must be set up and active before you can customize profiles using the DB2 Universal Driver.

7.2.1 Profile customization when using unqualified SQL


Unlike binding packages for COBOL applications, the customization for an SQLJ application consists of two steps. The first step is the online checking. It uses dynamic SQL to get additional information from DB2. Statements that cannot be dynamically prepared will not be online checked. Host variables in non-online checked statements have the potential to cause bind time or run-time errors due to data type mismatches. The second step is the actual bind that creates the DB2 packages. When using unqualified object names in your SQL statements (for example, SELECT EMPNO, LASTNAME FROM EMP in dynamic SQL), objects are prefixed based on the CURRENT SQLID (or CURRENT SCHEMA in V8). On the other hand, objects in static SQL statements are prefixed with the value specified on the QUALIFIER or OWNER (if QUALIFIER is not specified) BIND option. Because, as mentioned before, the customization of a serialized profile is using both dynamic (for the online checking) and static SQL (during the actual bind), there are two options on the db2sqljcustomize command: The -qualifier option is used in the db2sqljcustomize command to specify the object qualifier for the online check phase, and uses the CURRENT SQLID to set this qualifier in V7. (This might create a security issue because you normally cannot switch to any SQLID that you desire. It has to be the primary authorization ID or one of the secondary authorization IDs of the user doing the customization.) In DB2 for z/OS V8, on the other hand, the Universal Driver uses the SET CURRENT SCHEMA command, instead of SET CURRENT SQLID. No special authorization is necessary to execute SET CURRENT SCHEMA. Using the -bindoptions keyword, you can specify additional bind options supported by the database. Therefore, to perform a successful bind of a package using unqualified SQL (where the object qualifier is different from the package owner), you can specify the QUALIFIER keyword on the -bindoptions keyword. For example:
db2sqljcustomize ..... -qualifier DSN8810 -bindoptions QUALIFIER(DSN8810)

148

DB2 for z/OS and WebSphere: The Perfect Couple

7.2.2 Reducing the number of SQLJ-generated packages


As mentioned earlier in this publication, by default, the SQLJ customizer generates four packages per .ser file; one for each isolation level. There are two ways to influence the number of generated packages: Specify multiple .ser files in a single db2sqljcustomize command. Only generate a package for a single isolation level (that you actually need) per .ser file (instead of four).

Specifying multiple .ser files in one customize command


The SQL statements of all .ser files that you specify on a single db2sqljcustomize command are included in one set of (four) packages. This way, SQL statements of certain applications can be grouped together, for example:
db2sqljcustomize ... -rootpkgname HELLO -COLLECTION TESTBART Hello_SJProfile0.ser Employee_SJProfile0.ser

That will produce four packages, one for each isolation level: HELLO1, HELLO2, HELLO3 and HELLO4 in the TESTBART collection. This customizer option will be supported in RAD V6. (IBM Rational Application Developer for WebSphere Software (RAD) is the new name that WSAD will have starting with V6.)

Create only a package for a specific isolation level


To achieve this you can specify a single isolation level on the -bindoptions keyword during customization. You can also specify the -singlepkgname keyword to indicate its name, for example:
db2sqljcustomize ...-singlepkgname HELLOUR -COLLECTION TESTBART -bindoptions "ISOLATION(UR)" Hello_SJProfile0.ser

This will generate a single package HELLOUR in the TESTBART collection with isolation level UR. The customizer option -singlepkgname will be supported in RAD V6. (IBM Rational Application Developer for WebSphere Software (RAD) is the new name that WSAD will have starting with V6.) For more information see 7.4.6, Customization on page 187; and 11.2.2, Container-managed persistence entity Beans with SQLJ on page 273.

7.2.3 Using manual package versioning


The db2sqljcustomize command allows you to create a new version of a package (or override an existing version). By default, as is the case for traditional languages, a default (blank) version is used. This means that each time you bind a package into the same collection, the existing package is overwritten. The DB2 precompiler supports a version option that allows you to specify a version string, or you can use VERSION(AUTO) and DB2 will generate a version string for you. Similar functionality exists when customizing SQLJ programs by using the -pkgversion keyword. As with other languages using embedded SQL, you can specify a version string yourself, or you use AUTO. The usage of manual versioning by using customizer option -pkgversion version-id allows more control over the number of package versions created in DB2, for example:
db2sqljcustomize ... -singlepkgname HELL2 -COLLECTION TESTBART -bindoptions "VALIDATE(RUN) ISOLATION(UR)" -pkgversion VERSION1 Hello_SJProfile0.ser Chapter 7. SQLJ

149

Packages that use the same version string are overwritten when bound, whereas -pkgversion AUTO will always generate a new version, and can lead to an explosion of the number of packages in the system, especially in a development environment. The BIND package command to copy packages from one environment to the next is also easier when you manually specify the version string, than having to use the one generated by DB2.

7.3 Application design


In this section we look at the different ways to access DB2 via SQLJ in the J2EE environment. The roadmap from the client container to the DB2 at the back-end is long and has many paths, as shown in Figure 7-1. If the client container is a Web browser, we usually have a servlet as the access point. From the servlet we can call SQLJ directly, or we can call a session Bean (SB), that uses SQLJ to access DB2 data, or the session Bean can go through an entity Bean with container-managed persistence (CMP), or an entity Bean with Bean-managed persistence (BMP). If the client container is a stand-alone Java application, we can even issue SQLJ calls directly, without involving the WebSphere Application Server. In fact, after a close look, we see that there are really only two different approaches. Either we create the SQLJ statements ourselves, or they are created by WSAD when using CMP entity Beans. When writing the SQLJ statements ourselves, we isolate the statements in Java utility classes, that we can use from the different access points. We can then concentrate on the bold arrows in Figure 7-1.

Web Browser Java App/ Applet

Servlet

Java

SQLJ

BMP SB CMP

DB2

Figure 7-1 The SQLJ roadmap from the client container to DB2

With the focus on WebSphere Application Server, we do not look at the scenario where the client container is a Java stand-alone program. We will concentrate on the Web browser scenario. However, writing a Java stand-alone program that either calls SQLJ directly or uses session Beans as access point, use the code from the servlet described in the following sections. Accessing a session Bean from a Java stand-alone program is almost identical to accessing the session Bean from a servlet. For further information about creating a Java stand-alone program using EJBs, refer to EJB 2.0 Development with WebSphere Studio Application Developer, SG24-6819.

7.3.1 Best practice


One highly valued programming model is the Model-View-Controller (MVC) pattern. This pattern enables you to separate the business logic from the presentation layer, which is recommended in general. The J2EE way to implement the MVC model is to use servlets,

150

DB2 for z/OS and WebSphere: The Perfect Couple

JSPs, and EJBs, where EJBs represent the Model, JSPs represent the View, and servlets represent the Controller. There are two different kinds of Enterprise JavaBeans: Session Beans (SB) and entity Beans (EB). Entity Beans represent data (they correspond to a row in a DB2 table), while session Beans implement business logic. A common approach when designing EJB applications with entity Beans and session Beans is to use a facade in front of entity Beans that protects the persistent data layer, and controls all the client access. In this way, the session Bean can tie together multiple data source access into a single process, and act as a single point of entry into the business layer. Another benefit of using a session Bean facade to the entity Beans is performance. Enterprise Beans in their nature are distributed objects, and all calls to the Beans are remote calls. To improve performance, the 2.0 specification added a local interface to the Beans. This local interface is supported by WebSphere Application Server V5. Methods on the local interface are invoked directly on the Bean, which gives a much better performance, but then the caller must live in the same JVM as the entity Bean. Using the facade session Bean, we can decide only to use the local interface of the entity Beans.

Entity Beans - BMP vs CMP


Entity Beans come in two flavors. They can either have Bean-managed persistence (BMP) or container-managed persistence (CMP). The benefits of CMPs are that the persistence is managed for us (by the container); we do not have to write the code ourselves. This makes them faster to construct and much more robust. If the back-end is DB2, or another RDBMS, we recommend using CMP over BMP. If we, for whatever reason, decide not to use CMP, we should consider not using entity Beans at all. We might as well access DB2 directly from the session Bean. One of the benefits of entity Beans is that they ensure consistency when having concurrent updates to the same object. If concurrent updates are not likely to occur, we might be better off with the more simple solution without BMPs.

Session Beans - Stateless vs stateful A session Bean can either be stateful or stateless. The difference is that a stateful session Bean can maintain a state between calls on the Bean. We can use a stateful session Bean to
maintain a session with a client, but there are many other ways to obtain this functionality. Usually the session Beans are accessed from a servlet in the Web container, where sessions are an issue as well. If we already have some session handling in the Web container, why should we choose to add additional session handling in the EJB container? Another issue about stateful session Beans is that they demand a lot of work from the container, so they can easily become a performance problem. We do not believe stateful session Beans to be the predominant choice, and in fact, we would think twice before using them. Our recommendation is to keep the session information in the Web container, and use stateless session Beans.

Remote vs local interface


As mentioned above, a local interface to enterprise Beans was introduced in the 2.0 specification. Now we have two interfaces to an enterprise Beanthe local interface and the remote interface. The local interface can be used when the caller is living in the same JVM as the Bean, while the remote interface can be invoked from another JVM. In a production environment, we may want to deploy the Web container on a z/OS or LPAR other than the EJB container. This requires that the Beans that we accesses from the Web container must be accessed through the remote interface. As the enterprise Beans we want to access from the Web container are the session Beans, these should implement the remote
Chapter 7. SQLJ

151

interface, while the entity Beans that are accessed through a session Bean facade should use the local interface. This gives us the best combination of performance and scalability. Note: Stateless session Beans are pooled by the EJB container in WebSphere Application Server, which is a huge performance optimization. The price to pay for using the remote interface is little compared to the benefit of the scalability.

The data transfer object


As mentioned above, we use a session Bean as a facade to the entity Beans. To represent the data of the entity Bean, a data transfer object (DTO) is usually used. The DTO is used to pass data to and from the Web container. A DTO may reflect exactly the attributes of an entity Bean, but it does not have to. Some DTOs only contain some fields from the entity Bean, and other DTOs represent data from more than one entity Bean. There is not a strict one-to-one relation.

To Bean or not to Bean


Even though we may not want to use entity Beans, we always tend to use session Beans. There are several reasons for always using a session Bean as a facade to access DB2. First of all, it enforces the MVC architecture, leaving a well-defined spot for implementing the business logic. Second, and most importantly, is that the EJB container provides us with transaction handling. Using the transaction handling of the EJB container will make the application more robust, as connections to DB2 always are committed, rolled back, released to the connection pool, and so on. However, using enterprise Beans requires that we play by the rules of the EJB container, especially when it comes to handling exceptions. See 7.3.3, Exceptions and transactions on page 154, for further information about exception handling. Important: Make sure you understand the exception handling in the EJB container, as this is essential to obtaining the right behavior of the application. Before you write any code, come up with some coding guidelines with a thorough description of the exception handling.

The big picture


The following list summarizes the discussion above: We use a session Bean to implement business logic. We use a session Bean as a facade to the entity Beans. We access session Beans through their remote interface. We access entity Beans through their local interface. We prefer CMP over BMP. We prefer stateless session Beans over stateful session Beans, and manage the session in the Web container. We use data transfer objects to represent entity Bean data. We enforce the MVC pattern by using enterprise Beans, JSPs, and servlets. We isolate our own SQLJ statements in Java utility classes. Figure 7-2 on page 153 illustrates the above.

152

DB2 for z/OS and WebSphere: The Perfect Couple

Websphere Application Server


Web Container
1
Request

EJB Container
2
Remote Call

Servlet
Forward

SB

Local call

CMP

Web Browser
4
Response

DTO

SQLJ

DB2

JSP

Figure 7-2 Best practice overview

In the next section, we describe the complete flow in more detail, but for now let us have a look at the big picture: 1. The Web browser issues a request for a URL, which at some point reaches the servlet. 2. The servlet invokes a method on a stateless session Bean through its remote interface. The session Bean either calls a CMP through its local interface or calls the DB2 directly by issuing a SQLJ command. The result is returned to the servlet in a DTO. 3. The servlet sends the DTO to the JSP. 4. The JSP generates the HTML output and sends it back to the Web browser. Note: The JSP is actually just another servlet. When a JSP is invoked, it is translated into a servlet and then loaded to run in the Web container.

7.3.2 The detailed application flow


Above we described the best practices of application design, and showed the general application flow. In this section, we drill down into the details to see what is happening when a request from the client is issued. The detailed application flow is shown in Figure 7-3 on page 154.

Chapter 7. SQLJ

153

Browser Client
Input Page
1

WebSphere Application Server


Application Server
Web Container
Embedded HTTP Server

Input Page HTML

EJB Container EJB EJB EJB

Data Sources

HTML
2

13

JSP JSP JSP


11 12 3 5

10

Enterprise Enterprise Enterprise Enterprise Bean Enterprise Bean Bean Bean Bean
7 8

DO

Web Server

Servlet Servlet Servlet


6

Plug-in 4

JNDI

Connection Pool

DB2

Figure 7-3 Application flow

The flow is: 1. A Web client requests a URL in the browser (input page). 2. The request is routed to the Web server over the Internet. 3. The Web server immediately passes the request to the Web server plug-in. All requests go to the WebSphere plug-in first. 4. The Web server plug-in examines the URL, verifies the list of hostname aliases from which it will accept traffic, and chooses a server to handle the request. 5. A stream is created. The stream is the connection to the Web container. The Web container receives the request and, based on the URL, dispatches it to the proper servlet. 6. JNDI is now used to look up the session Bean requested by the servlet. 7. JNDI will direct the servlet to the corresponding EJB container, which then instantiates the EJB that is requested. 8. The session Bean will now go back into the JNDI either to look up an entity Bean, or to look up the datasource. If an entity Bean is used, the entity Bean will do the look up of the datasource. 9. The SQLJ statement is executed, and data is sent back to the enterprise Bean. 10.Data Objects (DOs), also known as Data Transfer Objects, are created and handed back to the servlet. 11.The servlet sends the DOs to the JSP. 12.The JSP generates the HTML that is sent back through the WebSphere plug-in to the Web server. 13.The Web server sends the HTML to the browser.

7.3.3 Exceptions and transactions


This section describes the basic concepts of exception handling for EJBs with a focus on the impact on transactions. Another issue is the handling of SQL warnings that have to be 154
DB2 for z/OS and WebSphere: The Perfect Couple

handled differently, as no exceptions are thrown. We start out by defining transaction demarcation.

Transaction demarcation
Determining when a transaction begins and ends is called transaction demarcation. We can choose to either control when transactions begin and end programmatically, by using Bean-Managed Transactions (BMT) demarcation, or we can delegate this to the container through container-managed transaction (CMT) demarcation.

Bean-managed transactions
Bean-managed transactions must explicitly declare when the transaction starts, what behavior is part of the transaction, and when it ends. This is accomplished through the use of the UserTransaction interface specified in the Java Transaction API (JTA). This interface provides the necessary methods for controlling the transaction. Example 7-8 shows a simple example on how to use the interface.
Example 7-8 Simple user transaction example // declare the user transaction UserTransaction transaction = null; try { // get a UserTransaction via JNDI look up InitialContext ctx = new InitialContext(); tran = ctx.lookup( java:comp/UserTransaction); // begin the transacition tran.begin(); // do transaction work, usually execute SQL statements, then commit tran.commit(); } catch ( Exception e ) { // rollback the transaction if any error had occoured if ( transaction != null ) transaction.rollback(); }

Only Beans that are declared to use Bean-managed transactions, via the deployment descriptor, may use the UserTransaction interface. The container throws an exception if doing otherwise. A UserTransaction is not restricted to the EJB container; it can be obtained in a servlet as well. We can set the transaction type either by manually editing the deployment descriptor or by using the editor in WebSphere Studio Application Developer, as shown in Figure 7-4 on page 156.

Chapter 7. SQLJ

155

Figure 7-4 Setting the transaction type in WebSphere Studio Application Developer

Note: Even though it is possible to manage the transaction ourselves, we do not recommend the use of Bean-managed transactions. The task quickly becomes quite complicated, which might lead to non-robust applications.

Container-Managed Transactions
The simpler and much more elegant solution is to let the container manage the transactions for you. There is no need to write any transaction logic, because this is handled by the container at run time. Instead of intertwining the code with transaction demarcation, we simply declare the Bean to use container-managed transaction demarcation in the deployment descriptor. In addition, we can declare additional transactional attributes that govern the behavior of the Beans in the transaction. The transactional behavior of CMTs can be set either globally at the Bean level, or on the individual methods of the Bean. Depending on how the transaction attributes are defined, the container will either start, continue, suspend, ignore, stop, or throw an exception on a transaction, when a Beans method is invoked. A detailed description of these attributes can be found in Chapter 8, Transaction management in a WebSphere environment on page 191. The container determines whether to roll back or to commit based on two different things. First of all, it is possible to mark the transaction for rollback only by calling the method setRollbackOnly on the SessionContext object. The container then guarantees that the transaction is rolled back when completed. However, it will not force an end to the transaction immediately. We can use the getRollbackOnly method on the SessionContext object to determine if the transaction has been marked for rollback. This is illustrated in Example 7-9.
Example 7-9 setRollbackOnly() on the sessioncontext try { // call DB2 } catch ( SQLException e) { if ( e.getErrorCoe() == 4 ) { getSessionContext().setRollbackOnly(); } } // Do something if the transaction is not marked as setRollbackOnly if ( getSessionContext().getRollbackOnly() == false ) { // Do something else

156

DB2 for z/OS and WebSphere: The Perfect Couple

Exceptions
The container also uses the exceptions to handle transactions, which we will take a close look at hereafter.

System exceptions The system exceptions in J2EE include unexpected RuntimeException, RemoteException,
EJBException, and all exceptions that inherit from them. Therefore, it may include both checked and unchecked exceptions. System exceptions represent more serious unexpected conditions within the system that are not business related, and that prevent the method from successfully completing. If the method is executed within a transaction, the transaction will be rolled back immediately. Any system exception that is not caught by a Bean will be caught by the container. The container will intercept the exception, and then throw back to the client either a java.rmi.RemoteException or a javax.ejb.EJBException, depending on whether the method was invoked through the remote interface or the local interface. Important: The container does roll back the transaction when a system exception is thrown. Usually we just propagate any system exception to the container, which will then throw the appropriate java.rmi.RemoteException or javax.ejb.EJBException.

Application exceptions The application exception in J2EE is a checked exception in Java terms. A checked exception
must either be caught in the method, or be represented in the throws clause of the methods signature. The Java compiler enforces this. If a checked exception is neither caught or declared in the methods signature, a compilation error occurs. Application exceptions are used to specify a logical error, a business logic error. Whether a transaction should be rolled back or committed depends on the business logic. Therefore, it is the responsibility of the application programmer to roll back the transaction if required. It is not the responsibility of the container. If any application exception should result in rollback of the transaction, the exception must be caught, and one of the following two scenarios must take place: Mark the transaction as rollbackOnly. This is done by calling the setRollbackOnly method on the session context object, as described in Example 7-9 on page 156. The container guarantees that the transaction is rolled back at the end. Notice that the method flow continues. Throw a system exception. The exception thrown can either be an instance of one of the general exceptions javax.ejb.EJBException or java.rmi.RemoteException, or any user-defined run-time exception. The method will be aborted immediately, and the transaction terminated instantly. The method flow is discontinued.

Chapter 7. SQLJ

157

Important: The container does not roll back the transaction when an application exception is thrown. Usually we catch any application exception, checked exception, in the Bean, nest it into an EJBException, and then throw the EJBException to tell the container to roll back the transaction.

7.3.4 SQL exceptions and SQL warnings


With the focus on DB2, we have a closer look at errors originating from the database, which can either be an SQLException or an SQLWarning. An SQLException is generated in these circumstances: When any SQL statement returns a negative SQL error code When a SELECT INTO SQL statement returns a SQL error code larger than 100 Any other error code on a SELECT INTO SQL statements, which corresponds to DB2 warnings, does not throw an SQLException. Instead, a SQLWarning is created, which is then silently added to the calling object. It is therefore obvious that we must handle exceptions and warnings in different ways.

SQLException
This is an actual exception that is thrown by the JDBC driver. This means that we must catch the exception in our Bean. SQLException is a subclass of java.lang.Exception and is therefore a checked exception. This means that we have to catch the exception in our Bean code if we want to roll back the transaction. In Example 7-10 we show how to do this.
Example 7-10 Handling of a SQLException #sql public static context MyContext with (dataSource=jdbc/ITSO1); try { MyContext context = new MyContext(); #sql [context] { INSERT INTO EMP VALUES (123,,,)}; } catch ( SQLException e ) { throw new EJBException( e); }

If the SQLJ statements are separated from the enterprise Beans and written in separate Java utility classes, we just propagate any application exception, including SQLException, to the calling client. The utility classes are often unaware of the context in which their methods are invoked. It is therefore unlikely that the utility classes can perform any sensible error handlingthis is left to where the business logic is implemented in the session Beans.

SQLWarning
As SQLWarnings are not thrown, we are obviously not able to catch them. SQLWarnings are added silently to the execution context. Each SQLJ statement is associated with an execution context. The execution context allows us to control how the statement is executed, and to retrieve information about the statement after the execution. We can, for instance, set a query time-out for the statement, or we can retrieve information about how many rows were affected by a statement. We can retrieve any SQLWarnings through the execution context. For more information about the execution context, see section 10.7 in DB2 for z/OS and 390: Ready for Java, SG24-6435.

158

DB2 for z/OS and WebSphere: The Perfect Couple

To check for a DB2 warning, we invoke the getWarnings method on the execution context after we execute the SQL statement. getWarnings returns the first SQLWarning object that an SQL statement generates. Subsequent SQLWarning objects are chained to the first one. Example 7-11 shows how to retrieve the SQLwarning via the execution context object.
Example 7-11 Handling SQLWarning #sql public static context MyConnectionContext with (dataSource=jdbc/ITSO1); MyConnectionContext MyContext = new MyConnectionContext(); ExecutionContext execContext = new ExcectionContext() // Execute the SQL #sql [MyContext, execContext] { SELECT LASTNAME INTO :lastname FROM EMP WHERE EMPNO = 100 }; // Check for SQLWarning objects SQLWarning warning = execContext.getWarnings(); if (warning != null ) { // Handle warning }

Tip: The ExecutionContext can be used for purposes other than just checking for SQLWarnings. The class has a number of methods that can be used to control the execution of SQL statements in SQLJ. Some methods are applicable before the associated SQL statement is executed, and some are only applicable after their associated SQL statement is executed. Note also that we have a connection context (Mycontext) and an execution context (execContext) in the example above. You can also acquire a default execution context from the connection context by using the following:
ExecutionContext execContext = MyContext.getExecutionContext();

7.4 SQLJ in WebSphere Studio Application Developer


In this section we describe how to use SQLJ in WebSphere Studio Application Developer (WSAD) Version 5.1. This version has full SQLJ support, including tools for customization of serialized profiles. First of all we take a closer look at how WSAD deals with SQLJ. WSAD has to do some additional work, as SQLJ is a language extension and not an application programming interface (API). As mentioned in 7.1.2, Using SQLJ on page 144, we write SQLJ statements that are identified by the #sql qualifier, and store them in .SQLJ source files. These source files are pre-processed by WSAD, generating a Java source file, where all the SQLJ statements are translated to Java (by invoking the sqlj preprocessor). SQLJ source files in WSAD have the extension .sqlj, for instance MySqlj.sqlj. This SQLJ source file will be translated into the Java source file MySql.java. WSAD automatically translates the SQLJ file each time the file is saved if the check box Window Preferences Workbench Perform build automatically on resource modification is selected, as shown in Figure 7-5 on page 160.

Chapter 7. SQLJ

159

Figure 7-5 WSAD preferences - Automatically build resource on save

7.4.1 Setting up the environment


WSAD has a few minor requirements for developing SQLJ applications. We have to use a project that supports Java development, like a J2EE project, WEB project, EJB project, or a Java project. The other requirement is that we must use one output directory for the project. SQLJ development is not supported for projects that have multiple output directories for each source folder.

WSAD preferences
Through the WSAD preferences accessible from Window Preferences Data SQLJ (Figure 7-6), we can control how WSAD works with SQLJ files.

Figure 7-6 WSAD SQLJ preferences

The fields are: SQLJ translator JAR file Full path and file name of the JAR file containing the SQLJ class library that implements SQLJ translation support. If DB2 is installed the file is <db2home>/java/sqlj.zip, where <db2home> is where DB2 is installed, by default C:\Program Files\IBM\SQLLIB.

160

DB2 for z/OS and WebSphere: The Perfect Couple

SQLJ translator class name Fully package-qualified name of the SQLJ class used for translating SQLJ statements. The default is sqlj.tools.Sqlj. SQLJ Java source folder Name to use for the folder containing SQLJ Java source files. This preference is only used if we choose to create a specific source folder when we define our SQLJ project. If the source folder and the output folder are the same, then generated Java files are put in the same folder as the SQLJ files. SQLJ customization script folder Name to use for the folder containing SQLJ Ant scripts. Color for SQL clause in editor Color in which SQLJ statements are displayed in the Java editor. Enable debugging from SQLJ file If selected, debugging will occur in SQLJ files, instead of the generated Java files. If you change this preference, you must rebuild the project for the change to take effect.

Team support
In almost every project, there is more than one developer involved, and therefore we can use the team support facilities in WSAD. This includes a version control system as CVS or Rational Clearcase. In these cases, it is a good idea to tell WSAD to treat sqlj files as text files. This is done in the preferences for team support, accessible via Windows Preferences Team File content, as shown in Figure 7-7. Click the Add button and enter sqlj, then click the OK button. WSAD will automatically choose ASCII as contents.

Figure 7-7 Adding sqlj files as text files

7.4.2 Create the server and the datasource


In this section, we describe how to create a new WebSphere Application Server and set up the datasource in WSAD. We need the server to run our application, and we need of course a datasource to get access to DB2.

Create a new server


To create a new server in WSAD, switch to the Server perspective. If the Server perspective is not visible, use Window Open Perspective Server. In the Server Configuration window, right-click the Server folder, and select New Server and Server Configuration, as shown in Figure 7-8 on page 162.

Chapter 7. SQLJ

161

Figure 7-8 Create a new server

This opens the wizard for creating a new server and server configuration. Enter a name for the server, and select WebSphere version 5.1 Test Environment in the server type list and click Finish (Figure 7-9). The new server shows up in the Server Configuration window.

Figure 7-9 Creating a new server and server configuration

To open the server configuration editor, double-click the server name in the Server Configuration window. In this editor, we create and maintain datasources.

162

DB2 for z/OS and WebSphere: The Perfect Couple

Setting up JAAS security entries


In our datasource that we are about to define (in the next step), we use an authentication alias (see Figure 7-13 on page 166). This requires us to set up a JAAS entry. To do so, select the Security tab of the Server, and click the Add button next to the JAAS Authentication Entries list (Figure 7-10). Then enter the user ID BARTR4 and its password. Click OK.

Figure 7-10 Create a JAAS entry

Create the datasource


We want to create a datasource named jdbc/ITSO1 and use the Universal Driver to create a type 4 connection to DB2 for z/OS. Open the server configuration (by double-clicking), and select the Data source page. The Universal Driver is not listed in the JDBC provider list, so we have to add a new JDBC provider. Click the Add button next to the JDBC provider list. Select IBM-DB2 in the Database type list, and DB2 Universal JDBC Driver Provider in the JDBC provider type list, as shown in Figure 7-11 on page 164, and click Next.

Chapter 7. SQLJ

163

Figure 7-11 Creating a JDBC provider, step 1

To use the Universal Driver we need three jar-files to be in the class path: db2jcc.jar, db2jcc_license_cu.jar, and db2jcc_license_cisuz.jar. The first file contains the driver, while the other two are licence files. When only access to DB2 for z/OS is required, it is sufficient to include db2jcc_license_cisuz.jar. Enter a name for the JDBC provider, T4nonXA, and make sure the class path is correct. Then select Finish (Figure 7-12 on page 165). The new JDBC provider now shows up in the list.

164

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 7-12 Creating a JDBC provider, step 2

Select the new JDBC provider, and click the Add button next to the datasource list. Select DB2 Universal JDBC Driver Provider in the list, and select the radio button labeled Version 5.0 data source, and click Next. This bring us to the window shown in Figure 7-13 on page 166.

Chapter 7. SQLJ

165

Figure 7-13 Creating a data source, step 1

Fill in the window as shown above. Specify ITSO1 as the datasource name and jdbc/ITSO1 as the JNDI name. Also make sure to select the proper Data source helper class name. As we plan to use CMP Beans, make sure to check the Use this data source in container-managed persistence (CMP) box. Click Next. This takes us to Figure 7-14 on page 167.

166

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 7-14 Creating a data source, step 2

Here we need to specify a number of Resource Properties to make the data source work properly. You must at least specify the following properties: databaseName driverType serverName portNumber EnableSQLJ Click Finish. This concludes the datasource setup. Note that in Figure 7-13 on page 166 we also specified a component-managed and container-managed authentication alias (BARTR4). This concludes the server (and data source) setup. Our DB2 location name, for example, DBD8. Since this is a type 4 connection, the driverType must be 4. Our hostname where DBD8 resides, wtsc54.itso.ibm.com. The portnumber DBD8 is listening on, 38070. As we are using SQLJ, make sure to specify True.

7.4.3 Using an SQLJ Java project


We are now ready to create a new Java project, and add SQLJ support to that project. Then we create a single SQLJ file, and have a look at what WSAD is doing under the covers. The task is done in the following steps:. 1. 2. 3. 4. Create a new Java project Enable SQLJ support. Create the SQLJ source file. Generate customization script.

Step 1: Create a new Java project


Start the wizard for creating new projects in WSAD via the menu File New Project. This opens the wizard. Select Java in the list on the left-hand side, then Java Project in the list on the right, and click Next. This takes us to the second page of the wizard. On this page we enter the name of the Java project, which is SQLJ Test. Clicking Next takes us to the final page of the wizard, which is shown in Figure 7-15 on page 168. On this page we select the button Add Folder. This brings up a new dialog. Click the Create new folder button, enter
Chapter 7. SQLJ

167

SQLJSource as the new folder name, and click OK. Click OK again, and answer Yes to the confirm dialog that is displayed next. This brings us back to the screen in Figure 7-15. Click Finish.

Figure 7-15 Create a Java Project

Step 2: Enable SQLJ support


We select the SQLJ Test project in WSAD, right-click, and select Add SQLJ Support from the pop-up menu. Make sure the project is selected in the list, and click Finish. Assuming that we already have set the preferences for SQLJ as discussed in 7.4.1, Setting up the environment on page 160, the entry field specifying the SQLJ JAR file is already filled in. After SQLJ is enabled for the project, we need to specify some additional information, as shown in Figure 7-16 on page 169. Select the project, select Properties from the pop-up menu, and select SQLJ Customization Script.

168

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 7-16 SQLJ customization script options

We only fill in the URL and the options, leaving the User and Password fields empty. The URL is the URL to the database to which the SQLJ is to be bound (jdbc:db2://wtsc54.itso.ibm.com:38070/DBD8). In the Options field we specify the options to the bind process, for instance, the DB2 collection name that will contain the bound packages. This is done by entering the -COLLECTION <collectioname> parameter. If we are using unqualified SQL statements, we can specify the qualifier used by entering -QUALIFIER ITSOUSER. Note: In DB2 Version 7, the options specified are case sensitive (-COLLECTION). They have to be in upper case. In DB2 Version 8, the option keywords are not case sensitive.

Step 3: Create the SQLJ source file


Select the SQLJ Test project, and select New Other from the pop-up menu. This starts the wizard. Expand the Data entry in the left list, and select SQLJ. Then select SLJ File in the list on the right, and click Next. In this next screen of the wizard, we enter a package name and a class name (as shown in Figure 7-17), and click Finish.

Figure 7-17 Create a new SQLJ file

The SQLJ editor is now open, and we can enter our SQLJ code. In this example, we just create a very simple SQLJ file with a context definition and one SQLJ statement, as shown in Example 7-12 on page 170. Save the SQLJ source (File Save).

Chapter 7. SQLJ

169

Example 7-12 Simple SQLJ source file package itso.sqljtest; import java.sql.*; import sqlj.runtime.ref.*; public class Test { #sql public static context MyContext with (dataSource=jdbc/ITSO1); public String select( String empno) throws SQLException { MyContext ctx = new MyContext(); String lastname = null; #sql [ctx] { SELECT LASTNAME INTO :lastname FROM EMP WHERE EMPNO = :empno}; return lastname; } }

Step 4: Generate the customization script


The last thing we need to do is generate the customization script. This script is used to customize the serialized profiles and bind the packages to DB2. The script is an Ant script. Ant scripts are 100 percent integrated in WSAD. By using these scripts, we can bind the packages directly from within WSAD to a DB2 system. To generate the Ant script, select the SQLJ Test project, and select Generate SQLJ Customization Script from the pop-up menu. Note: This section only describes how WSAD handles SQLJ. For examples on how to run Ant scripts, see Chapter 11, Sample application on page 245. Let us have a closer look at what WSAD has generated for us.

Directory structure and files generated by WSAD


The directory structure and files generated by WSAD in the above process is shown in Figure 7-18 on page 171. First of all, three directories are generated: SQLJ Source SQLJJavaSource SQLJAntScripts The first one is the one we explicitly created in step 1, where we added a source folder. By adding this source folder, we indicated to WSAD to keep our different items in different directories. Therefore WSAD automatically creates a directory for the Ant scripts, and a directory for the generated files. The names of these directories are the ones we specified in the WSAD preferences (see Figure 7-6 on page 160). If we had not added the source folder, all the files would have been located in the same directory.

170

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 7-18 The directory for the SQLJ test project

The SQLJ source file we created (Test.sqlj) is located in the SQLJ Source directory. Every time we save this file, WSAD invokes the translator and creates a new java file (Test.java) and a new profile file (Test_SJProfile0.ser). As the .ser file is generated each time we save the SQLJ source file, the timestamp in the .ser file is updated each time as well. This means that we need to bind again every time we save the SQLJ source file, if we want the SQL to run as static SQL all the time. Two files are created in the SQLAntScripts directory. The properties file contains information about the database, the target collection, and the mapping between each profile (.ser file), and the root package name for the profile. The XML file contains the Ant script itself. The information in the properties file can be edited through the dialog where we specify the SQLJ customization script options; see Figure 7-16 on page 169. The content of the file is shown in Example 7-13.
Example 7-13 The sqlj.project.properties file #Tue Mar 09 16:58:18 PST 2004 db.options=-COLLECTION SQLTEST db.url=jdbc\:db2\://wtsc54.itso.ibm.com\:38070/DBD8 pkg.root.itso.sqljtest.Test_SJProfile0=Test_S0

The Ant script file is updated each time we generate the script, which is step 4 above. The content of the file is shown in Example 7-14. We do not get into details about the content of the Ant script. It is a completely auto-generated file, and it works.
Example 7-14 The Ant script used to bind the packages <project name="Profile sqlj.customize.xml" default="customizeAll" basedir="."> <property file="sqlj.project.properties"/> <property environment="env"/> <property name="cp" value="${env.CLASSPATH}"/> <target name="customizeAll" depends=" itso.sqljtest.Test" > <property name="customizeAll" value="true"/> </target> <!-- You must ensure the rootpkgname for each profile does not --> <!-- conflict with an existing package in the database. --> <target name="itso.sqljtest.Test" unless="customizeAll" > <java fork="true" failonerror="true" classname="com.ibm.db2.jcc.sqlj.Customizer" classpath="${cp};;..\bin"> <arg value="-url"/><arg value="${db.url}"/>

Chapter 7. SQLJ

171

<arg value="-user"/><arg value="${db.user}"/> <arg value="-password"/><arg value="${db.password}"/> <arg value="-rootpkgname"/><arg value="${pkg.root.itso.sqljtest.Test_SJProfile0}"/> <arg line="${db.options}"/> <arg value="-path"/><arg value="..\SQLJJavaSource"/> <arg value="itso\sqljtest\Test_SJProfile0.ser"/> </java> <copy file="..\SQLJJavaSource\itso\sqljtest\Test_SJProfile0.ser" todir="..\bin\itso\sqljtest" /> </target> </project>

7.4.4 User-managed persistence


When we write our own SQLJ statements, we call this user-managed persistence. As described in 7.3, Application design on page 150, we want to keep our SQLJ statements in Java utility classes. Where these classes are located is up to the application developer to decide. In our sample application we have put the classes in a separate project, called ItsoSqlj. In this example, which is a part of the scenario in Chapter 11, Sample application on page 245, we are only using the employee table. The content of the project is shown in Figure 7-19. Three files are of special interest, which are the files with our Java code and SQLJ statements: DBAEmployee.java DBAEmployeeServlet.sqlj DBAEmployeeEJB.sqlj We will soon get back to the content of the files.

Figure 7-19 Content of project ItsoSqlj

Note: If we compare the above structure with the one from Figure 7-18, we notice that the generated files are located in the same directory. This is because we did not define a special folder for the source files.

172

DB2 for z/OS and WebSphere: The Perfect Couple

With user-managed persistence, we have to consider two scenarios to manage transactions: One scenario where we use container-managed transactions, and the other scenario where we write our own code for transaction handling. Container-managed transactions are covered by the examples with the session Bean and the BMP entity Bean. The servlet example covers how to write our own code for the transaction handling. Let us have a look at the code in the three aforementioned files. There is one Java file and two SQLJ source files. The SQLJ statements in the two SQLJ source files are identical, but we need two different files, because we have to handle the connection differently. The Java file contains common information and behavior for the two SQLJ source files. The SQLJ statements are kept in both SQLJ source files for clarity. In the SQLJ code we want access to the information in the DBAEmployee class. One way of doing this is to use inheritance. We want the Java classes generated from the SQLJ files to inherit from (the same as extend from) the DBAEmployee class. DBAEmployee is called the super class of any classes that extend from it (Figure 7-20).

public abstract class DBAEmployee

public class DBAEmployeeEJB extends DBAEmployee

public class DBAEmployeeServlet extends DBAEmployee

DBAEmployeeEJB.sqlj
Figure 7-20 SQLJ files and Java inheritance

DBAEmployeeServlet.sqlj

DBAEmployee.java
In our scenario we use the class empl.Employee as data transfer object (DTO) for the employee, which is located in another Java package, so we need to have an import statement. This statement tells the JVM where to find the class. The common information in DBAEmployee.java for the two SQLJ files (DBAEmployeeEJB.sqlj and DBAEmployeeServlet.sqlj) is the following: The datasource As we are connecting to the same datasource from both SQLJ source files, we put the name of the datasource in this class. Host variables SQLJ works with host variables. These host variables must be declared locally, and are of course identical for both SQLJ source files, as they relate to the attributes of the employee table. The type of the host variables must match the columns data type in DB2. See Chapter 4 of DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414, for a list of mappings between Java data types and DB2 data types. Utility methods

Chapter 7. SQLJ

173

Two utility methods are supplied. These methods copy data between the host variables and an employee object. employee2hostvars will copy the fields from the employee object to the host variables, while hostvars2employee will copy the host variables to the employee object. The entire source of DBAEmployee.java is listed in Example 7-15.
Example 7-15 DBAEmployee.java file package itso.sqlj; // The Data Transfer Object, representing an employee import empl.Employee; public abstract class DBAEmployee { /* ** The JNDI name of the datasource. jdbc/ITSO1 must be defined as a datasource in ** the Websphere Application Server */ protected static String DATASOURCE = "jdbc/ITSO1"; /* ** Host variables, used in the SQLJ statements */ protected String empno = null; protected String firstnme = null; protected String lastname = null; protected String workdept = null; protected String phoneno = null; protected String job = null; protected String sex = null; protected java.sql.Date birthdate = null; protected String midinit = null; protected java.sql.Date hiredate = null; protected short edlevel = 0; protected java.math.BigDecimal salary = null; protected java.math.BigDecimal bonus = null; protected java.math.BigDecimal comm = null; /* ** Copy the values of host variables to the employee object passed to the method. */ protected void hostvars2employee( Employee employee) { employee.empno = empno; employee.firstnme = firstnme; employee.lastname = lastname; employee.workdept = workdept; employee.phoneno = phoneno; employee.job = job; employee.sex = sex; employee.birthdate = birthdate; employee.midinit = midinit; employee.hiredate = hiredate; employee.edlevel = edlevel; employee.salary = salary; employee.bonus = bonus; employee.comm = comm; }

174

DB2 for z/OS and WebSphere: The Perfect Couple

/* ** Copy data from the employee, passed to the method, to the host variables */ protected void employee2hostvars( Employee employee) { empno = employee.empno; firstnme = employee.firstnme; lastname = employee.lastname; workdept = employee.workdept; phoneno = employee.phoneno; job = employee.job; sex = employee.sex; birthdate = employee.birthdate; midinit = employee.midinit; hiredate = employee.hiredate; edlevel = employee.edlevel; salary = employee.salary; bonus = employee.bonus; comm = employee.comm; } }

DBAEmployeeServlet.sqlj
We create the DBAEmployeeServlet.sqlj file as described in Step 3: Create the SQLJ source file on page 169. The important issue in this file is the way we create and handle the connection context. The program is shown in Example 7-16. In this example we explicitly retrieve a connection from the datasource and create the connection context with that connection. This is the old fashioned way to create the connection context.
Example 7-16 DBAEmployeeServlet.sqlj file package itso.sqlj; import import import import import java.sql.*; javax.naming.*; javax.sql.*; sqlj.runtime.ref.*; empl.Employee;

// #1 public class DBAEmployeeServlet extends DBAEmployee { // #2 #sql static context SqlContextNonUniversalDriver; // #3 private SqlContextNonUniversalDriver ivMyCtx = null; // #4 public DBAEmployeeServlet() throws SQLException, NamingException { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(DATASOURCE); Connection conn = ds.getConnection(); conn.setAutoCommit(false); ivMyCtx = new SqlContextNonUniversalDriver(conn); }

Chapter 7. SQLJ

175

// #5a public void create(Employee employee) throws SQLException, NamingException { employee2hostvars(employee); #sql [ivMyCtx] { INSERT INTO EMP VALUES ( :empno, :firstnme, :midinit, :lastname, :workdept, :phoneno, :hiredate, :job, :edlevel, :sex, :birthdate, :salary, :bonus, :comm ) }; } // #5b public Employee findByPrimaryKey(String key) throws SQLException, NamingException { #sql [ivMyCtx] { SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL, SEX, BIRTHDATE, SALARY, BONUS, COMM INTO :empno, :firstnme, :midinit, :lastname, :workdept, :phoneno, :hiredate, :job, :edlevel, :sex, :birthdate, :salary, :bonus, :comm FROM EMP WHERE EMPNO = :key }; // Create an Employee object Employee employee = new Employee(); hostvars2employee(employee); return employee; } // #6a public void commit() throws SQLException { #sql [ivMyCtx]{ COMMIT }; ivMyCtx.close(); } // #6b public void rollback() throws SQLException { #sql [ivMyCtx]{ ROLLBACK }; ivMyCtx.close(); } }

The steps are: 1. When we create a new SQLJ file by using the wizard, as shown in Figure 7-17 on page 169, we do not have the possibility to specify a super class. This has to be done manually by adding extends DBAEmployee to the class definition. 2. This line defines the connection context suitable for all drivers. When processed by the SQLJ preprocessor, this line will create an inner Java class called SqlContextNonUniversalDriver. This generated class is the connection context class that wraps the DB2 connection. 176
DB2 for z/OS and WebSphere: The Perfect Couple

Note: The name SqlContextNonUniversalDriver does not indicate that the Universal Driver cannot use this construct. It only indicates that this was the only way to set up a connection context prior to the Universal Driver. Using the Universal Driver provided, an additional way to set up a connection context is available, as shown in Example 7-17. 3. We need an instance of the connection context class defined in the previous step. This instance is on the class level, as we want to use the same connection until we either call commit or roll back. 4. We create the instance of the connection context class in the constructor of the class. To create the connection we first do a lookup of the datasource by calling JNDI. When we have the datasource, we get a connection from it, and create the connection context class with the received connection. Notice that we call setAutoCommit(false) on the connection object to avoid it from committing every time we are issuing an SQL statement. 5. The create method and the findByPrimaryKey method are using the connection in the same way. It is simply used between the brackets, telling the preprocessor to use that particular connection context when it creates the Java code. We do not close the context. 6. When we want to commit our SQL statements we call commit. That will execute an SQL COMMIT and then close the connection context. The same applies for rollback. Note: In this example we are saving the connection context inside the class. This means that all SQL statements we want to execute in the same unit of work have to be defined in the class. If we have SQL statements in different classes, and we want to execute the statements in the same unit of work, we would create the connection context outside the class, and pass it as a parameter to each method.

DBAEmployeeEJB.sqlj
We create the DBAEmployeeEJB.sqlj file as described in Step 3: Create the SQLJ source file on page 169. This SQLJ file is created with the requirement that it is used within a transaction. Furthermore, we create the connection context in an easier way, without doing a look up of the datasource. This way of creating the connection context is much simpler, but is only supported by the Universal Driver. The program is shown in Example 7-17.
Example 7-17 DBAEmployeeEJB.sqlj file package itso.sqlj; import import import import import // #1 public java.sql.*; javax.naming.*; javax.sql.*; sqlj.runtime.ref.*; empl.Employee; class DBAEmployeeEJB extends DBAEmployee {

// #2 #sql public static context SqlContextUniversalDriver with (dataSource="jdbc/ITSO1"); // #3 public DBAEmployeeEJB() throws SQLException { } // 4a public void delete( String key) throws SQLException {

Chapter 7. SQLJ

177

SqlContextUniversalDriver myCtx = new SqlContextUniversalDriver(); // SQLJ Statement #sql [myCtx] { DELETE FROM ITSOUSER.EMP WHERE EMPNO = :key }; // Hand over the connection to Websphere, that will close it when needed myCtx.close(); } // 4b public void update( Employee employee) throws SQLException { SqlContextUniversalDriver myCtx = new SqlContextUniversalDriver(); employee2hostvars( employee); // SQLJ Statement #sql [myCtx] { UPDATE ITSOUSER.EMP SET FIRSTNME = :firstnme, MIDINIT = :midinit, LASTNAME = :lastname, WORKDEPT = :workdept, PHONENO = :phoneno, HIREDATE = :hiredate, JOB = :job, EDLEVEL = :edlevel, SEX = :sex, BIRTHDATE = :birthdate, SALARY = :salary, BONUS = :bonus, COMM = :comm WHERE EMPNO = :empno }; // Hand over the connection to Websphere, that will close it when needed myCtx.close(); } // 4c public void create( Employee employee) throws SQLException, NamingException { SqlContextUniversalDriver myCtx = new SqlContextUniversalDriver(); employee2hostvars( employee); #sql [myCtx] { INSERT INTO ITSOUSER.EMP VALUES ( :empno, :firstnme, :midinit, :lastname, :workdept, :phoneno, :hiredate, :job, :edlevel, :sex, :birthdate, :salary, :bonus, :comm ) }; // Hand over the connection to Websphere, that will close it when needed myCtx.close(); }

178

DB2 for z/OS and WebSphere: The Perfect Couple

// 4d public Employee findByPrimaryKey( String key) throws SQLException, NamingException { SqlContextUniversalDriver myCtx = new SqlContextUniversalDriver(); // SQLJ Statement #sql [myCtx] { SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL, SEX, BIRTHDATE, SALARY, BONUS, COMM INTO :empno, :firstnme, :midinit, :lastname, :workdept, :phoneno, :hiredate, :job, :edlevel, :sex, :birthdate, :salary, :bonus, :comm FROM ITSOUSER.EMP WHERE EMPNO = :key }; // Hand over the connection to Websphere, that will close it when needed myCtx.close(); // Create an Employee object Employee employee = new Employee(); hostvars2employee( employee); return employee; } }

The steps are: 1. As with DBAEmployeeServlet, we want to extend the Java class DBAEmployee, which we must do manually by adding extend DBAEmployee to the class definition. 2. We create the connection context by directly specifying the datasource, which is only supported by the Universal Driver. 3. We do not do anything in the constructor of the class. Note that we do not have a connection context at the class level to instantiate. 4. In every method where we are executing SQL, we do the same three things. First we create a connection context, then we execute the SQL, and finally we close the connection context. When we create the connection context, the transaction manager will ensure that we always use the same connection within the same transaction. When we close the connection context, we are not closing the underlying connection, we just tell the transaction manager that we are done with the connection, that is, to set the connection in a valid state for commit. Note: We do not need the commit and rollback methods anymore; this is left to the transaction manager.

Servlet
In the Web container, where servlets are executed, we are not in the scope of any transaction. When it comes to handle a connection to DB2, we have two possibilities. Either we create a user transaction and execute our statements within the boundaries of this user transaction, or we can operate on the connection itself, by calling commit and rollback.
Chapter 7. SQLJ

179

Attention: Even though we are giving the examples here, remember that accessing SQLJ directly from the servlet is not a best practice. See 7.3.1, Best practice on page 150. In the examples in this section, we call the method getEmployeeFromRequest. This method will extract information about an employee from the HttpServletRequest object, and return an instance of the data transfer object empl.Employee with the employee information from the request. The method is shown in Example 7-18. In the examples, we do not go into details about exception handling. We simply catch and throw exceptions to illustrate where things can go wrong, and how to get on. Exception handling usually differs from application to application, but it is very important to have good coding guidelines for the exception handling process.
Example 7-18 Create a data transfer object based on information in the request private Employee getEmployeeFromRequest( HttpServletRequest req) throws Exception { // Create an employee instance Employee employee = new Employee(); // Fill in information from the request employee.empno = (String) req.getParameter("EMPNO"); employee.firstnme = (String) req.getParameter("FIRSTNME"); ... employee.bonus = new BigDecimal( (String) req.getParameter("BONUS")); employee.comm = new BigDecimal( (String) req.getParameter("COMM")); // return the employee instance return employee; }

Using the connection


In this example we show how to call SQLJ without a transaction. We have isolated the SQLJ statements in the two Java utility classes as described above, and we must use the DBAEmployeeServlet class, as this is the one with commit and rollback methods. A simple code snippet is shown in Example 7-19.
Example 7-19 Create an employee without using a transaction public void createEmployee(HttpServletRequest request) throws Exception { // #1 Employee employee = getEmployeeFromRequest(request); // #2 DBAEmployeeServlet dbaEmployee = new DBAEmployeeServlet(); try { // #3 dbaEmployee.create(employee); // #4 dbaEmployee.commit(); } catch ( Exception e) { // #5 dbaEmployee.rollback(); throw e; } }

180

DB2 for z/OS and WebSphere: The Perfect Couple

The Steps are: 1. First of all we create an instance of the Employee data transfer object with information taken from the request. 2. Then we create an instance of the class DBEmployeeServlet. In the constructor of this class the connection is created. 3. Then we invoke the create method passing the employee object as the parameter. 4. If the call to DB2 succeeds, no error will be thrown and we call commit on the dbaEmployee object. 5. If the call to DB2 failed, an exception is thrown. As we need to roll back the connection, we must catch the exception and call rollback on the dbaEmployee object.

Using a user transaction


In this example we show how to call SQLJ from within a user transaction. Like in the example above, we use the DBAEmployeeServlet class, but instead of calling commit and rollback on the connection, we do it on the user transaction. A code snippet is shown in Example 7-20 on page 173.
Example 7-20 Create an employee using a user transaction import javax.transaction.UserTransaction; public void createEmployee( HttpServletRequest request) throws Exception { UserTransaction tran = null; try { // #1 Employee employee = getEmployeeFromRequest( request); // #2 InitialContext ctx = new InitialContext(); tran = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); // #3 tran.begin(); // #4 DBAEmployeeServlet dbaEmployee = new DBAEmployeeServlet(); dbaEmployee.create( employees); // #5 tran.commit(); } catch ( Exception e ) { // #6 if ( tran != null) tran.rollback(); throw e; } }

The steps are: 1. As before, we get an employee from the request. 2. Then we get a UserTransation object, by a lookup in JNDI. The UserTransaction is the interface used to handle the boundaries of a transaction manually. WAS comes with a built-in Transaction Manager that handles the transaction issues in the EJB container. Based on information in the deployment descriptors for the enterprise Beans, the Transaction Manager automatically creates or reuses a transaction. To give us the possibility to get full control of the transaction boundaries, we can obtain an instance of a UserTransaction object, which is the programmers hook into the

Chapter 7. SQLJ

181

Transaction Manager. This is useful if we, for instance, want to extend the transaction boundaries to the Web container. 3. The we start the scope of the transaction. 4. Then we create an instance of the DBAEmployeeServlet class and invoke the create method passing the employee object as the parameter. 5. If the call to DB2 was successful we commit the transaction. 6. If the call to DB2 failed then we roll back the transaction.

Session Bean
In this example we show how to call SQLJ from a session Bean. We now use the DBAEmployeeEJB utility class. We do not have to care about either the connection or the transaction. The method on the session Bean is invoked within the boundary of a transaction, and we only have to obey the EJB container rules for exception handling. A code snippet is shown in Example 7-21. The method createEmployee is a method on the session Bean that is accessed through the remote interface.
Example 7-21 Calling SQLJ from a session Bean public void createEmployee(Employee employee) throws EJBException { try { // #1 DBAEmployeeEJB dbaEmployee = new DBAEmployeeEJB(); // #2 dbaEmployee.create(employee); } catch (Exception se) { // #3 throw new EJBException(se); } }

The steps are: 1. First of all we create an instance of the DBAEmployeeEJB utility class. 2. Then we invoke the create method passing the employee object as the parameter. 3. If the call to DB2 would fail, we catch the exception and throw an EJBException. Throwing the EJBException will tell the container to roll back the transaction. The big difference between the above example and the example with the servlet is that we do not have to worry about any connection or transaction. This makes the code much easier to read, more simple, and more reliable.

Entity Bean, Bean-managed persistence


In this example we show how to call SQLJ from an entity Bean with Bean-managed persistence. The code is very similar to the code in the session Bean. A code snippet is shown in Example 7-22.
Example 7-22 Calling SQLJ from an entity Bean with Bean-managed persistence public void ejbCreate( Employee employee) throws CreateException{ try {

182

DB2 for z/OS and WebSphere: The Perfect Couple

DBAEmployeeEJB dbaEmployee = new DBAEmployeeEJB(); dbaEmployee.create( employee); } catch ( Exception se) { throw new CreateException(); } }

The only difference with the session Bean example is that we throw a CreateException and not an EJBException. The reason for this is that creating an entity Bean is a part of the Beans life-cycle methods, and they are only called by the container. These methods are not accessible from the client. On the Beans home interface there will be a create method that takes an Employee object as a parameter. When a client, usually a session Bean, is calling this method, the container will call the ejbCreate method. There are special rules for these call back methods, for instance, that the ejbCreate method must throw a CreateException. See EJB 2.0 Development with WebSphere Studio Application Developer, SG24-6819, for a detailed description of how to manage the lifecycle of an entity Bean with Bean-managed persistence.

7.4.5 Container-managed persistence


When we are using container-managed persistence, it is the deployment process that generates the SQL needed to manage the EJBs. When SQLJ support is enabled, the deployment process generates one .ser file containing all the SQL statements. This .ser file must be handled in exactly the same way as described in the sections above where we created the SQL statements ourselves. SQLJ is enabled at the EJB module level. This means that if we have two EJB modules, we can enable SQLJ on one of them, and still use JDBC for the other one. This is of interest if we are accessing two different databases, where only one of them supports SQLJ.

CMP mapping
The mapping between the enterprise Beans and the DB2 tables is stored in a file called map.mapxmi. The information in this file supplies the deployment tool with information on how to do the mapping between the enterprise Beans and the database. One piece of information in the file is whether to use SQLJ. The map itself associates fields in the enterprise Beans with table columns. This map can be obtained in three different ways, which are called mapping strategies: Top down This approach is also known as forward engineering. Based on existing entity Beans, new tables are created. This is the easiest way to create the mapping when no legacy (existing) database is involved. The limitation is that we are not in charge of the database design. Bottom up This approach is also known as reverse engineering. Based on existing tables, new entity Beans are automatically created for you. The limitation is that we do not design the Beans ourselves, so they may not match our business needs. Meet in the middle This approach is the compromise of the other two approaches, and is the most flexible one. Based on existing tables and existing entity Beans we create the mapping manually.

Chapter 7. SQLJ

183

We do not have any of the limitations imposed by the other approaches, but the maintenance of the mapping is more cumbersome. Figure 7-21 summarizes the three approaches.

Top-Down

Bottom-Up

Meet in the Middle


Define

EJB Definition EJB Mapping Schema

Define

Generated

Generated

Generated

Manual

Generated

Imported

Imported

DB2

Create

Existing

Existing

Figure 7-21 Mapping strategies for CMP Beans

Which of the three approaches to use depends on the situation. If the database already exists, we will either use the bottom-up or the meet-in-the-middle approach, depending on how close the database design is to the business model we want for our Beans. Important: We have to be careful with the top-down approach, as the physical database might end up being a nice design, but with extremely poor performance. Especially in applications with a large number of online transactions, there can be a big difference between the logical and the physical database design. Always have a DBA check the database design.

Example of the bottom-up approach


In our sample scenario we used the bottom-up approach. See Chapter 11, Sample application on page 245. A comprehensive walk-through of each approach can be found in EJB 2.0 Development with WebSphere Studio Application Developer, SG24-6819.

Enabling SQLJ support for an EJB module


Once we have set up the WSAD environment to support SQLJ, as described in Setting up the environment on page 160, it is very simple to enable SQLJ support for the container-managed entity Beans: 1. In the J2EE hierarchy view, select the map under the Maps section of the EJB Modules, and double-click to open. See Figure 7-22 on page 185. 2. Select the root EJB module in the Overview section. 3. In the Properties section expand the SQLJ property if it is not already expanded. 4. Select the SQLJ:Is using SQLJ in the Properties column. 5. In the Value column, click the drop-down menu and select true. 6. Save the changes. 184
DB2 for z/OS and WebSphere: The Perfect Couple

Figure 7-22 Container-managed persistence and SQLJ

Next time we generate deployment code the .ser file is created in the Websphere_deploy folder that is associated with the DB2 back-end.

EJB Query Language (EJB QL)


When we are using container-managed entity Beans we do not have direct access to the database. There is an abstraction level from the entity Beans to the physical database beneath. To be able to find and retrieve entity Beans that meet certain criteria, we must be able to do this by referencing the ejb level, not the database level. To do this we can use the EJB Query Language (EJB QL). Similar to SQL that operates on schema definitions containing tables and fields, EJB QL operates on a similar definition called the abstract persistence schema. This schema defines how the entity Beans are mapped to DB2. The abstract persistence schema can be viewed in the Overview window in the Data perspective in WSAD. When defining EJB QL, we are limited to referring only to elements described in the abstract persistence schema. Figure 7-23 on page 186 show the abstract persistence schema for our sample database.

Chapter 7. SQLJ

185

Figure 7-23 Abstract persistence schema

EBJ QL looks very much like traditional SQL. A query consists of a SELECT clause, a FROM clause, and an optional WHERE clause. The SELECT clause must always return a single value. This value can either be a field of an entity Bean or an object reference.
SELECT e.lastname FROM Emp AS e WHERE e.empno = ?1 SELECT Object(e) FROM Emp e WHERE e.lastname like ?1

The first statement returns a collection of the CMP field lastname (a collection of String objects), while the second statement returns a collection of Emp instances. Note that the AS keyword in the first example is optional; it is used for clarity only. Note: Even though EJB QL looks like ordinary SQL, it is a new typed expression language. A EJB QL expression is a query based on objects and return objects; it never returns a row from DB2. The EJB QL statements are mapped to methods of our entity Beans through the deployment descriptor. Example 7-23 is part of the deployment descriptor from our sample application. It maps the EJB QL statement with the method findByLastName(String lastname) to the Employee entity Bean.
Example 7-23 EJB QL example from our sample application <entity id="ContainerManagedEntity_1076532486891"> <ejb-name>Employee</ejb-name> .......... <query> <description>EJBQL query for employees in 1 department</description> <query-method> <method-name>findByLastName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql>SELECT OBJECT(e) FROM Emp e WHERE e.lastname like ?1</ejb-ql> </query>

186

DB2 for z/OS and WebSphere: The Perfect Couple

</entity>

WebSphere extensions
WebSphere Application Server provides extensions to EJB QL to make it more specific and flexible. These extensions include subqueries, ORDER BY and HAVING clauses, and expressions with SQL date and time formats. Note that these extensions are vendor-specific. If we choose to use them, we might not be able to deploy our Beans in another EJB 2.0 compliant container. A comprehensive walkthrough of the EJB QL and WebSphere extensions can be found in EJB 2.0 Development with WebSphere Studio Application Developer, SG24-6819. Tip: EJB QL is a relatively new specification and is evolving constantly. As EJB QL uses the same syntax as SQL, more and more of the reserved words in SQL will also become reserved words in EJB QL. It is therefore recommended that we do not use any reserved words from SQL in our EJB QL statements.

7.4.6 Customization
An important task when using SQLJ is the customization and bind process. This is the step where the DB2 packages are created and bound to DB2, making our SQL statements execute as static SQL. As long as the packages are not bound to DB2, our SQL statements will run as dynamic SQL. The customizer will automatically (by default) bind the packages against the database. This means that once the profiles have been customized against DB2, we must have a matching package bound in the database. If not, an SQLException is thrown, indicating a package not found exception. The customization process adds DBMS-specific information to the serialized profile. In case of DB2, this information includes the package name, a timestamp indicating when the customization took place, and a consistency token used to ensure that the database package matches the profile. When using the Universal Driver, the profiles remain platform independent after customization, because SQLJ implementations are required to ignore customization information they do not know about. All DB2 implementations across the DB2 family use the same customization. We do not have to customize again when switching from a DB2 for Linux, Unix, and Windows to DB2 for z/OS and OS/390 when using the DB2 Universal Driver.

Isolation levels
SQLJ allows you to change the isolation level at the beginning of a new transaction, using the SET TRANSACTION ISOLATION LEVEL clause. However, each package in DB2 is created to use a specific isolation level. Therefore, the profile customizer, by default, creates four packages, one for each isolation level. The names of these packages consist of the root package name and a suffix of 1 through 4, corresponding to the isolation levels UR, CS, RS, and RR respectively. Since a package name in DB2 can be up to eight characters long, the root name must not exceed seven characters. In our sample scenarios, we use the root name CPHEMP, resulting in these four packages: CPHEMP1 - For isolation level UR (uncommitted read) CPHEMP2 - For isolation level CS (cursor stability) CPHEMP3 - For isolation level RS (read stability) CPHEMP4 - For isolation level RR (repeatable read)

Chapter 7. SQLJ

187

If we only want to enable one of the packages, we can either free the packages for the unwanted isolation levels, or we can tell the profile customizer to create the required package only for a specific isolation level. We do this by specifying this bind option:
-singlepkgname pkgname -bindoptions isolation isolation level

Where isolation level is the isolation level we want the package to use, and we must use the DB2 syntax (UR, CS, RS, RR), not the JDBC notation (1, 2, 3, 4). In WSAD, we must specify this in SQLJ customization script dialog along with the package name, as shown in Figure 7-16 on page 169.

Online checking
By default, the profile customizer runs with online checking enabled if we have entered a value in the URL field in the SQLJ customization script dialog; see Figure 7-16 on page 169. When online checking is enabled, the SQLJ customizer queries the DB2 catalog on the target database server to verify whether our SQLJ statements will be able to run on that server. This is a great benefit, as we have all our SQL statements validated on bind time, and not at run time. Online checking will recognize errors or potential problems such as: Misspelled names (table names, view names, column names, and so on) Lack of authorization (for example, an INSERT statement on a table for which the package owner lacks permission) Data type mismatches (for example, if we are trying to update a numeric column with a string value) Another important feature of the online checking is that it will help the DB2 optimizer to find the best access path. If online checking is disabled, the optimizer might find a poor access path due to lack of information.

Example and tip


A walkthrough of the customization for our sample scenario can be found in 11.2.2, Container-managed persistence entity Beans with SQLJ on page 273. Tip: The DB2 profile printer db2sqljprint is a tool that can be used to print the information contained in a serialized profile in human-readable form. Essentially, what the profile printer does is to read a serialized profile, deserialize it, and print all profile entries, including any DB2 customization information that is present.

7.4.7 WAS 5.1.0.1 FixPak


SQLJ does not work properly in WebSphere Application Server Version 5.1 on the distributed platform, and because WSAD uses WAS 5.1, the problem is present in WSAD as well. The problem results in a NullPointerException thrown by WAS, as illustrated below.
Example 7-24 NullPointerException thrown by WAS java.lang.NullPointerException at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.setString( WSJdbcPreparedStatement.java:1178) at com.ibm.db2.jcc.sqlj.f.setString(f.java:1275)

188

DB2 for z/OS and WebSphere: The Perfect Couple

Unfortunately, at the time of writing there was no FixPak for WSAD that solved the problem. However, FixPak 5.1.0.1 for WAS solves the problem, and this FixPak can be applied manually to the WAS V5.1 installed under WSAD.

How to get the FixPak


FixPak WAS 5.1.01 can be downloaded from the following site:
http://www.ibm.com/support/us/all_download_drivers.html

Enter Application Server + 5.1.0.1 in the entry field, and select -Updates (code fixes) in the combo box. Then submit the search. The result of the search will not be unique, but gives you a limited number of items. The correct FixPak is named WebSphere Application Server 5.1 Cumulative Fix 1. Select the package and scroll down to the table with the downloadable packages. Click the item named Windows - Base and follow the download instructions. The downloaded file is named was510_cf1_win.zip, which must be unzipped before the FixPak can be installed. Important: Do not unzip the FixPak with pkUnzip, as this might destroy the image. Use WinZip instead.

How to install the FixPak


Locate the directory where WebSphere Application Server V5.1 is installed under WSAD. It should be something like <WSADdir>\v5.1.1\runtimes\base_v5. For safety reasons, take a backup of the directory. Start a command prompt and switch to the directory of the unpacked FixPak, and execute the command file updateWizard.bat. The command file might report errors. For instance, it might tell you to run the setupCmdLine.bat from your WebSphere Application Server installation. Switch to the <WSADdir>\v5.1.1\runtimes\base_v5\bin directory and execute the setupCmdLine.bat. Switch back to the FixPak directory and start updateWizard.bat again. Follow the instructions in the update wizard. Note: Make sure that the JDK used during the update is the one used by WSAD. If you have installed another JDK outside WSAD, using this other JDK might lead the update to fail. To verify that the update is complete, start a V5.1 server from within WSAD. In the console you should see the information shown in Figure 7-24.

Figure 7-24 Verifying FixPak WAS 5.1.0.1

7.5 Deployment to WebSphere Application Server


Deploying a SQLJ application to WebSphere Application Server is straight forward. There are only a few extra issues related to the SQLJ side of the project. Otherwise, deploying an enterprise application using SQLJ does not differ from deploying an enterprise application without SQLJ.

Chapter 7. SQLJ

189

The thing to remember is to do the profile customization. Without this, the SQLJ will run as dynamic SQL. The profile customization can even be executed from within WSAD using the Ant script that WSAD creates. This is described in Step 4: Generate the customization script on page 170. We use the following customization options:
-COLLECTION SG246319 -QUALIFIER ITSOUSER -BINDOPTIONS "OWNER(ITSOUSER)"

The entire deployment process is described in 11.6, Deployment of the EAR file on page 307.

7.6 Summary
With WebSphere Studio Application Developer now fully supporting the development of applications using SQLJ, it is very simple to use static SQL in our applications instead of ordinary JDBC. Especially if we are using Enterprise JavaBeans with container-managed persistence, the use of SQLJ is very easy. The only extra work is the profile customization, which is a very small price to pay for the benefits obtained by using SQLJ.

190

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 8.

Transaction management in a WebSphere environment


This chapter discusses transaction management within WebSphere and DB2. With multiple methods of ensuring transactional integrity, this chapter will help you make better decisions on how to choose and implement appropriate transactional support for your application. This chapter discusses the following transaction concepts: What transactions are WebSphere resources and transaction support DB2 as a transaction manager DB2 as a resource manager Considerations for two-phase commit processing

Copyright IBM Corp. 2005. All rights reserved.

191

8.1 What transactions are


A transaction is a set of work for which either all individual work items or no items are performed. A failure of a subset requires that the entire work set is undone. This all-or-none attribute is called atomic. For example, assume an application attempts to update three tables within a transaction. A failure during the update of the third table would undo all updates to the first and second table within the transaction. This atomic attribute ensures that all dependent operations are completed in full. A transaction is also known as a Logical Unit of Work (LUW).

8.1.1 Local transactions


If a transaction references a single resource during the transactions life span, the resource itself can guarantee atomicity of the transaction. Since a resource can manage its own atomic state, the transaction is then known as a local transaction or a single-phase commit unit of work. The relational database example mentioned above represents a local transaction since only a single relational database manager (RDBM) is referenced during the transaction and the RDBM maintains the atomic action of the transaction. A DB2 UDB for z/OS subsystem is a resource that can manage its own transaction state and support local transactions. In local transactions executing on DB2 UDB for z/OS, the unit of work is started implicitly by updating, inserting, or deleting a table within DB2. In some resource managers the start of the transaction is explicitly noted to the resource. In other resource managers, such as DB2, the local transaction begins implicitly with the first insert, update, or delete statement. If a failure occurs, the transaction is terminated and all work is undone (also known as a rollback). Transactions are ended with a call to the resource manager to attempt to finalize the unit of work. Many resource managers label this action as a commit. For most resource managers, a commit implies that changes during the transaction will be hardened to a non-volatile facility (such as DASD), which could be used for recovery if a failure where to occur. Commit also makes all of the changes within the transaction visible to other units of work. Since there is only one resource within a local transaction, the commit instruction occurs in one phase, a commit request and an acknowledgement from the resource management with success or failure of the commit. DB2 accomplishes the commit process by hardening log records to DASD. The log records contain the before and after images of the changes that occurred during the transaction. This allows DB2 to provide integrity and restore the committed transaction if a failure were to occur before the updated data can be written to disk in its proper data position.

8.1.2 Global transactions


Transactional applications sometimes need to update two or more resource managers within an atomic unit of work. While resources can maintain their own consistency for local transactions, the ability to remain atomic across access to multiple resources requires special actions by all involved parties. This is known as a global transaction. In a global transaction, resources and agents of the transaction can execute on different physical and logical platforms while maintaining the atomic attributes of a local transaction. The communication between all involved parties to ensure transactional integrity can be implemented with multiple methodologies; the most common is known as the two-phase commit process.

Two-phase commit
In a two-phase commit transaction, one agent acts as the transaction manager (or coordinator) and all other agents are known as resource managers or participants. Within the

192

DB2 for z/OS and WebSphere: The Perfect Couple

transaction, resources are enlisted in the transaction by the transaction coordinator as they are referenced. Enlistment allows the transaction manager to maintain a list of all resources participating in the unit of work and allows all the participants to share a common token to identify the transaction for all parties. While application work is occurring within the transaction, if a resource encounters a failure, a notification is sent to the coordinator and the coordinator instructs all the participants to roll back. If the transaction manager fails, the resource managers recognize that a communication failure occurred and immediately roll back the transaction. Once application work at all of the resources is complete, the process for committing the actions works in two phases. Depicted in Figure 8-1, the transaction manager sends a prepare to all of the participants indicating that there will be no additional work in the transaction. The resource (managers) hardens all changes and acknowledges the prepare request. Once the resource hardens its changes, the resource manager considers the transaction in doubt since the resource only knows its own state and has not been informed of the other resources state by the transaction coordinator.

Figure 8-1 Two-phase commit processing

If the transaction manager does not receive a successful prepare acknowledgement from all of the resources, the transaction manager instructs all of the resource managers to roll back. If the transaction manager receives successful acknowledgement, all resources are then instructed to commit the unit of work. The commit instructions inform the resources that all of the resources in the process have now agreed to commit and that each resource should log the final commit and the transaction will no longer be considered in doubt. Once all of the resources acknowledge the commit, the transactions manager logs a forget record for the transaction to indicate that no further action or processing is required for the transaction. If a failure of a resource or transaction manager occurs while the transaction is considered in doubt by any of the resources, the resources must maintain integrity until communication with the transaction manager is re-established and the transaction outcome can be determined. This implies that resources, such as locks acquired during the transaction and are held until commit, must continue to be held until the final transaction outcome can be determined.

Chapter 8. Transaction management in a WebSphere environment

193

Manual action can also instruct resource managers to commit or roll back a transaction without re-establishing communication with the transaction manager. This is known as a heuristic decision. Although not required, in some cases a transaction coordinator can also be a resource manager.

8.2 WebSphere transaction management


Whether implicitly or explicitly, transactions begin and end as the result of application actions. In a J2EE environment, the behavior and attributes of these transactions are defined to the execution environment via deployment descriptors. WebSpheres support for transactions is really only applicable to session Beans. In a servlet or JSP environment, transaction support is the sole responsibility of the application developer, and WebSphere does little but provide interfaces that can be referenced. Entity Beans do not manage transactions since entity Beans represent data, not a series of actions to be taken against data. As a result, there is little transactional information associated with an entity Bean other then the ability to be referenced in a transaction and to have the underlying persistence layers support local and/or global transactions.

8.2.1 Transaction demarcation


While not required for local or single-phase commit transaction, applications have the ability to execute within a transaction, also known as a transaction context. Once a transaction has been started the application is executing within that transaction context. A transaction context is required for two-phase commit coordination. The demarcation (that is, the start and end) of a transaction can occur with or without explicit action by an application. The responsibility of transaction demarcation is determined based upon how the Bean is deployed. Transaction demarcation can be the responsibility of the application or the responsibility of the container. When an application is deployed, its deployment descriptors indicate if the application will manage its transaction context manually or if the application prefers that the container manages the transaction context. Container-managed transactions (CMT) are used when the container, with guidance from the application deployer, transparently begins, ends, or suspends transaction contexts. While generally not recommended, some application developers choose to explicitly manage their own transaction demarcation. These are known as Bean Managed Transactions (BMT). As mentioned before, specification of transaction management demarcation is only applicable for session Beans. By design, entity Beans do not control the start and end of transaction contexts, they are representations of data, not actions. As a result, entity Beans are managed transactionally by the applications that invoke them. Servlets and JSP execution environments, as per the J2EE specification, do not provide container-managed transaction support and are implicitly Bean-managed transactions. To configure demarcation, WebSphere Studio Application Developer (WSAD) uses

deployment descriptors. A deployment descriptor defines whether the Bean will be BMT or
CMT, as shown in Figure 8-2 on page 195. To access the deployment descriptor, use the EJB perspective and double-click the EJB deployment descriptor within the EJB project. Once the deployment descriptor has been opened, either click the Bean name from the Overview tab, or click the Bean tab located at the bottom of the EJB deployment descriptor window.

194

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 8-2 Deployment Descriptor: Bean options for transaction management

Transaction demarcation is independent of actions performed against resources within the transaction. Applications should not attempt to commit or roll back individual resources within a transaction context; instead, implicit action for CMTs or explicit UserTransaction methods for BMTs should start and end transactions. Performing actions such as getConnection or con.close do not affect the transaction. Important: Within an EJB transaction, do not attempt to issue transaction controls to individual resources. All transaction demarcation should occur independently of the resources involved within the transaction. You can close or open a connection multiple times within a transaction and not affect the transaction or its atomicity.

8.2.2 Bean-managed transactions and the UserTransaction interface


This interface is part of the J2EE specification and allows an application to manage its own transaction context. The javax.transaction.UserTransaction interface is retrieved from the EJBContext and allows a Bean to explicitly begin, commit, rollback, getStatus, and perform other functions as well. To use the javax.transaction.UserTransaction interface, first retrieve the EJBContext by using the EJBContext.getUserTransaction() method. This method will return a UserTransaction class from which the getStatus() method can be called to determine if a transaction already exists. This call will return int STATUS_NO_TRANSACTION if no transaction exists. A subsequent call to the UserTransaction.begin() method can be used to start the transaction. Resources such as a database connection or a JMS queue can be accessed as they normally would be accessed. There is no need to start the transaction before acquiring a connection; however, no work should be performed on the connection before starting a UserTransaction. Whether executing in a local or global transaction, the interaction with a resource should not change. Once the application work is completed, the UserTransaction can be commit() or rollback().

Chapter 8. Transaction management in a WebSphere environment

195

Attention: Bean-managed transactions (BMT) should not use the setRollbackOnly() method; instead they should explicitly roll back the UserTransaction and call the rollback() method. It is important to differentiate between transaction demarcation and access to resources. If a call to a method does not need to manage the beginning or the end of the transaction, the method does not need to instantiate a UserTransaction object. Applications should only instantiate the UserTransaction object if specific action is required in order to begin or end the transaction. For example, a transaction session Bean could call many methods that write to a database or send JMS messages without the need to reference or manage the transaction. As a result, classes and methods developed for use within a Bean-managed transaction should be relatively easy to port to an EJB with Container Managed Transactions (CMT). It is a good idea not to mix the management of the transaction with access to resources (including exception management). Instead, isolate the resource access and the use of the UserTransaction interface.

8.2.3 Transaction types (for container-managed transactions)


When a session Bean and its methods are deployed to a server with container-managed transaction support, the container needs general guidelines on how and when it should start, terminate, or suspend a transaction. The deployment descriptor indicates whether a method needs to be executed within a transaction context. As shown in Figure 8-3, the WSAD Assembly Descriptor tab within the EJB Deployment Descriptor defines what transaction environment a method requires.

Figure 8-3 Method declaration of transaction type

Once the entire Bean or the Bean methods have been selected, a user can choose the transaction type, as shown in Figure 8-4 on page 197.

196

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 8-4 Container transaction types for method execution

The transaction types are defined as follows: Supports If a client calls the method with a transaction context, the transaction context is used. If the client calls without a context, the Bean behaves in the same manner as Not Supported. If a client calls the method with a transaction context, the transaction context is used. If the client calls without a transaction context, a new transaction context is created. If a client calls with a transaction context, the current context is suspended and a new transaction context is created. The new transaction context is used for the execution of the Bean. At completion, the transaction context is ended and the original transaction context is resumed. If the client calls without a context a new context is created. The client must call with a transaction context. Failure to do so throws a TransactionRequiredException. The client must call without a transaction context. Failure to do so results in an exception being thrown. If a client calls with a transaction context, the context is suspended and the method is executed without a transaction context. Once the method completes, the original transaction context is resumed. If the client calls without a context, the method is invoked without a context.

Required

RequiresNew

Mandatory Never Not Supported

If you do not explicitly choose a transaction type for the Bean or its methods, the default setting is Requires. For most applications there is no need to change the default. The bulk of applications use the Requires option to ensure that two-phase commit coordination can be supported.

Chapter 8. Transaction management in a WebSphere environment

197

EJBContext setRollbackOnly()
Container-managed transactions do not have the ability to explicitly commit or roll back a transaction. If an application encounters an error while working with a resource and wants to throw an exception, the container will not always automatically roll back the transaction. As a result, it is important that applications have the ability to explicitly set a flag to prevent the transaction from committing. The method setRollbackOnly() on the EJBContext allows an application to prevent the container from committing the transaction, which ultimately forces a roll back.

8.3 WebSphere resources and transaction support


As an implementor of the J2EE specification, WebSphere supports both local and global transactions and can be either a transaction manager or a resource (manager) within a transaction. An applications actions and deployment descriptors determine transactional behavior, and the resources exploited within those transactions must support the actions of the application. As a result, requirements for transaction support of resources are dictated by the application behavior, and resource support can limit the potential actions of an application.

8.3.1 Resource interfaces


WebSphere for z/OSs transaction support is implemented by exploiting zSeries-specific operating system facilities for transaction support, known as RRS, and WebSpheres implementation of support for the X/Open transaction (XA) standard. These two interfaces provide WebSphere with the ability to access resources within both local and global transactions.

Recoverable Resource Services


A component of the zSeries Operating System (z/OS), Recoverable Resource Manager Services (RRS), provides a logical partition (LPAR) or parallel sysplex-wide mechanism for implementing two-phase commit coordination. By providing a centralized facility with centralized logging, two-phase commit processing on the zSeries platform can benefit from a high-performance and highly functional mechanism for both managing and participating in two-phase commit workload. Any resource that implements the RRS interface can be managed by RRS within an atomic unit of work. Many zSeries products have implemented RRS-compliant interfaces including DB2 for z/OS, IMS, CICS, and WebSphere MQ. These interfaces allow WebSphere Application Server to be a transaction manager or a resource manager by exploiting these RRS services.

X/Open transaction (XA) support


Since RRS function is available on zSeries only, prior to WebSphere Application Server for z/OS Version 5, resources needed to be RRS compliant to participate in a global transaction within WebSphere Application Server for z/OS. To support open standards and increase interoperability, WebSphere Application Server for z/OS Version 5 implements the X/Open standard for global transactions, also known as the XA specification. As a transaction manager, WebSphere can provide two-phase commit support for transactions that access both XA resources and RRS resources within the same transaction. Although the underlying interfaces are different, the application accesses each resource in the same manner and WebSphere transparently ensures transaction integrity across both interfaces.

198

DB2 for z/OS and WebSphere: The Perfect Couple

Single resource global transactions


WebSphere also provides the ability for a single-phase commit resource, also known as a Resource Managed Local Transaction (RMLT), to be accessed in a global transaction context. With this facility WebSphere recognizes if only one resource is accessed during the transaction and allows a non-XA or non-RRS enabled resource to be accessed. If an attempt is made to access a second resource the transaction is immediately rolled back. WebSphere also implements a two-phase commit variation known as last participant optimization, which allows a single-phase commit resource to operate within a two-phase commit transaction. This is accomplished by WebSphere ensuring that the single-phase commit resource is the last resource to receive the prepare instruction, and acknowledgement of the prepare implies that a prepare and a commit were successful. There are some functional limitations with this approach and significant care should be taken before implementing it.

8.3.2 Resource transaction isolation


An important attribute regarding resources and how they are exploited within a transaction is the transaction isolation level. Explained in more detain in Transaction isolation on page 210, transaction isolation determines the separation and integrity of actions performed at a single or multiple resources within the transaction. This crucial function attribute can drastically affect a transactions ability to overwrite work from another transaction, affecting transaction integrity, or can serialize access to resources, which affects performance. Attention: Transaction isolation is an important factor affecting transaction integrity and performance. Be sure to visit the section on Transaction isolation on page 210.

8.3.3 Configuring JDBC resources


WebSphere allows the configuration of JDBC resources for two-phase commit support via its administration panels. For DB2 access, the administrator can configure JDBC providers who either support a DB2 Universal JDBC driver, a DB2 Universal JDBC Driver supporting XA, or a DB2 for z/OS local JDBC Driver (RRS). The difference between the DB2 Universal JDBC driver (Universal driver) and the DB2 for z/OS local JDBC 2.0 driver is described in 1.7.3, IBM DB2 Legacy Driver on page 22. Since the Universal driver is IBMs strategic connectivity mechanism for Java access to DB2, this discussion focuses solely on the configuration of the Universal driver, which supports both RRS and XA interfaces for global transaction support. You can display, edit, and add the Universal driver providers (XA and non-XA) within the Resources JDBC Provider tab of the administration console application. For information on configuring these providers see 3.3, Data source definitions in WAS V5 on page 51. Your installation should have these drivers available, as displayed in Figure 8-5 on page 200.

Chapter 8. Transaction management in a WebSphere environment

199

Figure 8-5 Universal JDBC Providers

Which JDBC provider to exploit depends on whether an application requires two-phase commit support and what type of JDBC driver will be used.

DB2 Universal JDBC Driver Provider


When WebSphere is deployed on a z/OS platform, datasources within this provider allow both single-phase commit and two-phase commit processing via a type 2 JDBC driver connection. In order to provide two-phase commit processing, WebSphere and the Universal Driver exploit RRS-compliant interfaces. When configuring this driver, you must set the datasources custom property (within Resources JDBC Providers DB2 Universal JDBC Provider DataSources your-datasource-name Custom Properties) driverType to 2, as shown in Figure 8-6 on page 201. The ability to have a non-XA resource-compliant JDBC Provider participate in a global transaction is unique to the zSeries platform. Do not attempt to use the non-XA Universal Driver for two-phase commit processing on any other platform including WSAD.

200

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 8-6 DB2 Universal JDBC Driver DataSource Custom Properties

DB2 Universal JDBC Driver Provider (XA)


The Universal Driver provider with XA support allows datasources to support both single-phase commit and two-phase commit processing via a type 4 JDBC driver. As described in 1.7.2, JDBC driver types on page 21, a type 4 JDBC driver is pure Java and exploits the relational database servers native network protocol for accessing data. For distributed communications, DB2 supports the open standards Distributed Relational Database Architecture (DRDA) protocol. For more information on how the type 4 Universal JDBC driver implements the XAResource interface, see 8.5.1, DB2s support for XA on page 204. When configuring the XA datasource, you must specify datasources custom property driverType as 4. A summary of supported JDBC driver functions is listed in Table 8-1. Use this table when defining new JDBC providers. You should not define DB2 Universal JDBC Driver (XA) for type 2 JDBC connectivity when using WebSphere for z/OS.
Table 8-1 Summary of JDBC Driver Provider support for WebSphere z/OS Driver provider driverType property Supports local transactions (single-phase commit) YES Supports global transactions (two-phase commit) YES

DB2 Universal JDBC Driver

Chapter 8. Transaction management in a WebSphere environment

201

Driver provider

driverType property

Supports local transactions (single-phase commit) YES YES

Supports global transactions (two-phase commit) NO YES

DB2 Universal JDBC Driver DB2 Universal JDBC Driver (XA)

4 4

8.4 DB2 as a transaction manager


In addition to WebSphere, DB2 UDB for z/OS has the ability to act as a transaction manager for global transaction applications that access two or more DB2s or other DRDA resources. As part of the DRDA specification, DB2 supports two-phase commit transactions across DRDA servers, including other DB2 UDB for z/OS subsystems and DB2 UDB for Linux, UNIX, and Windows, and DB2 Connect systems. When DB2 is the transaction manager, two-phase commit atomicity across multiple physical resources can be implemented while WebSphere perceives all of the servers as a single resource. WebSphere and DB2 UDB for z/OS as a transaction manager are not mutually exclusive. DB2 UDB for z/OS can be the transaction manager for a branch of a WebSphere-managed two-phase commit tree.

8.4.1 Configuring and exploiting DB2 as a transaction manager


To access a remote DB2, applications need to reference a remote DB2 subsystem by its location name. For type 2 JDBC connections the local DB2 is always initially referenced before the location specified in the datasource is reached. The local subsystem is determined by the properties file for the JDBC driver (db2sqjjdbc.properties for the legacy driver (non-Universal driver), DB2JccConfiguration.properties for the Universal JDBC driver). The property db2.jcc.ssid determines the subsystem name; or, if not defined, the value within DSNHDECP contained in the linklist (or STEPLIB) will be used for local connectivity. For type 4 JDBC connections, the IP address and port defined within the datasource determine the DB2 subsystem that is referenced first. While this subsystem is not local, it provides the same function as the type 2 driver local subsystem ID that is providing communications routing to the target location. For the purposes of this discussion, this subsystem for both type 2 and type 4 connections is know as the first contact subsystem. In most implementations, the databaseName within the datasource definition matches the location name of the first contact subsystem. Whether type 4 or type 2, you can specify a location (or location alias in DB2 UDB for z/OS Version 8), which is not the first contact subsystems location name but instead a location defined within the Communication Database (CDB) of the first contact DB2 subsystem. In this implementation the first contact subsystem behaves as a connection gateway and potentially as a transaction manager. The diagram in Figure 8-7 on page 203 shows multiple configurations where DB2 UDB for z/OS can be the transaction manager.

202

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 8-7 DB2 UDB for z/OS as the transactions manager

The figure shows multiple approaches to reaching the remote locations sanjose and dallas from a WebSphere application. The WebSphere datasource databaseName can reference either a target location where application data resides or it can reference the location name of the gateway subsystem, newyork. If the target location is used, tables residing at the location can be referenced with two-part names and tables at other locations can be referenced with three-part names. Alternatively, the first contact machine can be referenced in the datasource and three-part names used to reference tables at other locations. Tip: When using DB2 as a transaction manager, the transaction manager subsystem is the location referenced in the WebSphere datasource. A three-part table name is a reference to a table within an SQL statements, which concatenates the location as the highest qualifier of the table reference. Three-part names have the form of location.qualifier.table, where the location is the subsystem where the table resides, as defined within the executing systems communications database (CDB). The qualifier is the owner or explicit qualifier or the table, and the table is the name of the table. Restriction: When executing on DB2 UDB for z/OS an application cannot reference more then one location within a single SQL statement.

8.4.2 DB2 configuration requirements


In order to provide remote connectivity between a local DB2 subsystem and a remote DB2 subsystem, the local subsystem must have a properly configured communications database (CDB). The communications database allows for the configuration of the communications protocol to be exploited, USERID mapping, and the name of the remote location. Information regarding the configuration of the communications database can be found in the DB2

Chapter 8. Transaction management in a WebSphere environment

203

Universal Database for z/OS Version 8 Administration Guide, SC18-7413, or Distributed Functions of DB2 for z/OS and OS/390, SG24-6952. To support all variations of the configuration, it is a good idea to bind the JDBC packages at the destination DB2 subsystems. Since the JDBC driver packages are versioned, multiple DB2 JDBC driver maintenance levels can be bound at the same server. At a minimum, the JDBC driver packages must be bound at each of the locations referenced within a DB2 datasource and the local or first contact subsystem must have the remote package bound into the local collection. To allow remote package execution, the local collection needs to include references to the remote subsystem packages. By default, JDBC executes within the NULLID collection. The NULLID collection should therefore include the packages at each of the locations. Refer to DB2 Universal Database for z/OS Version 8 Command Reference, SC18-7416, for information on binding packages at remote locations.

8.4.3 DB2 or WAS as a transaction manager


Since both WebSphere and DB2 have the ability to manage transactions that only access DB2 or DRDA resources, who is a better manager? Surprisingly, recent performance measurements indicate that communications to remote subsystems using the type 4 Universal JDBC driver (XA) have higher throughput and reduced elapsed time when compared to communications that connect to the local DB2 and subsequently connect to the remote DB2. Since the use of DB2 as the transaction manager for the DB2 transactions requires a traversal through the bulk of the JDBC layer and then requires an additional hop through the local DB2, there is a penalty to reprocess the request to simply move it across the network. In April 2004, a new class of zSeries processors designed specifically for Java execution was announced. A combination of function embedded in z/OS, the JDK, and within zSeries PR/SM allows these specially licensed engines, known as zSeries Application Assist Processors (zAAPs), to only execute instructions that originate from a Java Virtual Machine. These Java dedicated engines are fully functional CPUs with the cost savings benefit that they do not increase a machines MSU or MIP rating, and as a result do not affect traditional software licensing charges. By moving the processing of transaction management from DB2 to a pure Java implementation, the software cost of the transactions can be reduced by removing the DB2 DDF hop.

8.5 DB2 as a resource manager


As a resource manager, DB2 supports multiple protocols for global transaction support. Since XA support is a new feature, this section focuses on the XA support provided in DB2 UDB for z/OS Version 7 and Version 8.

8.5.1 DB2s support for XA


The DRDA protocol provides support for the management of two-phase commit transactions across remote databases. Without explaining in significant detail, DRDAs implementation of two-phase commit in DB2 UDB for z/OS Version 7 differs from the XA standards implementation. Not only are the specific protocol flows different, the recovery methodology after a failure also differs. The DRDA recovery implementation can be categorized as peer to peer, where any resource can initiate recovery. In XA, the transaction coordinator is the initiator of recovery in all cases. As a result of these differences, the Universal Driver cannot 204
DB2 for z/OS and WebSphere: The Perfect Couple

simply convert XA requests to DB2 UDB for z/OS Version 7 DRDA requests without an explicit new function to support XA at the DB2 server. To avoid impacting the V7 code stability by retrofitting XA support back into DB2 V7, a different approach was taken. To provide this support in Version 7, the state of a XA global transaction is stored in a facility that is available for DB2 at restart. For data sharing, every member of a data sharing group needs to be able to determine the status of any transaction regardless of which member processed the transaction. To provide a group-wide transaction tracking mechanism, V7 provides a new table, SYSIBM.INDOUBT, and a method to inform other members what the outcome of their in-doubt transactions should be, based upon instructions from the transaction manager. Due to DB2s data sharing implementation policy of reading, but not writing to other members logs, members cannot roll back or commit transactions on each others behalf. The SYSIBM.INDBOUT table in Version 7 is created by a utility program shipped with the XA-enabled type 4 JDBC driver. The utility, DB2T4XAIndoubtUtil, creates the table and defines a package that DB2 exploits to track transaction status in the table (via static SQL). These objects or packages should not be created, altered, or dropped without the use of the utility. Detailed instructions for the utility are provided in the DB2 Universal Database for z/OS Version 7 Application Programming Guide and Reference FOR JAVA, SC26-9932. As depicted in Figure 8-8, Version 8 replaces the SYSIBM.INDOUBT table with changes in the DRDA protocol flow to support the XA protocol, and by exploiting the Shared Communications Area (SCA) within the Coupling Facility (CF). The SCA provides cross-member coordination when operating in data sharing mode, which results in the entire group sharing transaction status information. This storage is exploited by DB2 to manage the list of global transactions and their state across members so that DB2 UDB for z/OS can be considered an available XA resource, even when all members of the group have not been restarted. The Version 7 solution requires inserts into a DB2 table to coordinate the transaction status for every transaction. When one member fails, it is very likely that the INDOUBT table will have retained locks (until the member is restarted). Those may prevent transactions running on other members from running. Version 8s exploitation of internal memory structures, specialized log records, and the SCA provides improved scalability. For high-volume two-phase commit XA global transactions, IBM strongly recommends that customers exploit DB2 UDB for z/OS Version 8. Figure 8-8 shows the two implementations of tracking global transaction (XID) status.

DB2 V7 WebSphere
XID in table SYSIBM. INDOUBT

DB2 V8
XID in CF Structure (SCA)

DB2 V7

Universal JDBC T4

DB2 V8

Figure 8-8 Native DDF XA support

8.5.2 Global transaction support


For resources, such as DB2 UDB for z/OS, global transactions can present architectural challenges. Within a single unit of work, a J2EE application may exploit Enterprise

Chapter 8. Transaction management in a WebSphere environment

205

JavaBeans (EJBs) that reside on physically different servers. Each of those Beans can access a single DB2 server. This single unit of work spans multiple separate connections but logically behave as if they were the same thread. See Figure 8-9 for a depiction of how a single transaction can span multiple physical machines.

WebSphere WebSphere Application Server Application Server JDBC T4 JDBC T4 AIX AIX

WebSphere WebSphere Application Server Application Server

WebSphere WebSphere Application Server Application Server JDBC T4 JDBC T4 AIX AIX

DB2 UDB for z/OS DB2 UDB for z/OS

z/OS

Figure 8-9 Single Global Transaction crossing multiple Application Servers

In Version 7, DB2 introduced a feature known as global transaction support for JDBC applications via the datasource interface. This allows multiple threads to behave as the same transaction. When multiple JDBC connections are participating in a global transaction, all branches of the transaction are sharing locks. Uncommitted changes made by one branch are visible to every branch. When implementing a shared connection architecture such as above, consider the following restrictions: Parallel sysplex is not supported for global transactions. All agents must process against a single subsystem (a single member of a data sharing group) in order to share locks. Claim/drain processing is not supported for lock sharing. This implies that CREATE, DROP, ALTER, GRANT, and REVOKE may time out or deadlock between branches. In Version 7, updates to a partitioning key may also result in a deadlock or time out. An explicit LOCK TABLE may time out or deadlock between branches.

8.6 Considerations for two-phase commit processing


In order to ensure atomic transaction integrity across multiple resources, two-phase commit transactions require additional work for all parties. Consideration should be given to the adverse affects of this functional benefit. Specific focus should be given to overall performance throughput and failure impact.

JDBC

z/OS

JDBC

8.6.1 Lock duration


For global transactions, it is important to recognize that locks, which are normally held to commit or beyond, are held for longer periods of time then local transactions. While this time can vary significantly between transactions, locks will always be held longer since the application needs to reference and coordinate with additional resources beyond the local DB2. Application planning should focus on reducing the amount of time a transaction lasts within DB2.

206

DB2 for z/OS and WebSphere: The Perfect Couple

For example, if the other resources within the transaction do not maintain locks, such as a Java Messaging Service (JMS) or WebSphere MQ Series, applications should exploit DB2 as the last resource enlisted in the transaction. If DB2 is the last resource accessed in the transaction, locks will be held for a shorter period of time, and potentially will not need to be held while work is being performed at other resources. Conversely, if DB2 is accessed first in the transaction, then locks will continue to be held while other resources are accessed. This can significantly reduce overall concurrency.

8.6.2 Failure impact


In order to ensure atomic transaction integrity across multiple resources, two-phase commit transactions can cause complex failure considerations for resource managers. Resources are forced to accept the possibility of an outage caused by failures at other resource managers or at the transaction manager.

8.6.3 Lock impact from failure


If a resource manager failure occurs at the transaction coordinator or at the resource managers before the prepare phase begins, all surviving entities know to roll back the transaction automatically, and the impact of the failure may simply limit the ability for new transactions to start since some of the resource managers will be unavailable. With planning to remove single points of failure, a failure of a resource manager before the prepare phase of the transaction usually results in a roll back of the active transactions and newly scheduled transactions are able to exploit the redundant services. Global transactions frequently cause architectural concern in cases where the transaction coordinator fails between issuing the prepare instruction and the final commit instruction. When a failure of this type causes a resource manager to put the transaction in an in-doubt state, as described in Global transactions on page 192, the transaction must be resolved before access to the locks held by the failing transaction can be granted to other transactions. This is required to ensure transactional integrity because at this point the resource manager does not know if the other resources have committed or rolled back the transaction. In architectures where multiple WebSphere Application Servers are serving a global transaction workload, a failure in one application server can leave a critical lock locked due to in-doubt transactions. As a worst case, consider an insert that forces an index split. The transaction going in-doubt implies that the entire index is unavailable due to a transaction manager failure at another physical machine. At DB2 UDB for z/OS, no other transactions can access that index until the transaction manager gives instruction on how to resolve the in-doubt transaction, or a heuristic (manual) decision is made.

8.6.4 How to recover from failures


The key focus in all failure cases is to restart failed components as quickly as possible. Regardless of which component failed, quick recovery and reduced failure impact is to provide a mechanism to process the transaction log of all resources to resolve any in-doubt transactions after the failure. As part of the design of two-phase commit and the XA implementation, restart of the failed component will resolve any in-doubt transactions, assuming communication between all the pertinent resources is available. Quick restart will minimize the impact of the failure to other transactions that were not executing on the failed component.

Chapter 8. Transaction management in a WebSphere environment

207

DB2 UDB for z/OS in-doubt transaction resolution


For DB2, in-doubt transaction resolution of remote DRDA connections (using TCP/IP) occurs via the resync IP port. During the initial exchange of information during the start of the global transaction, a resync IP address and port is passed back to the requestor. The resync port is used to resolve any outstanding inboubt transactions. The normal DDF port (also known as the SQL port) may be shared by multiple DB2 subsystems within a data sharing group or used to route workload across multiple physical machines via z/OS Sysplex Distributor. The unique resync port ensures that the transaction coordinator has a mechanism to reestablish communications with the member holding the in-doubt transaction. As mention earlier, only the original member processing the transaction can resolve (commit or rollback) the transaction.

208

DB2 for z/OS and WebSphere: The Perfect Couple

Chapter 9.

DB2 locking in a WebSphere environment


This chapter discusses the many options within WebSphere for z/OS V5 and DB2 UDB for z/OS, which affect overall transaction concurrency and locking within DB2. The breadth of this topic prevents us from getting into every detail of DB2 locking facilities. Our goal is to provide some definitions of terms, an understanding of the most common DB2 locking principals and WebSphere deployment descriptors, and some general considerations for lock behavior for WebSphere applications. This chapter contains the following: DB2 locking Transaction isolation WebSphere transaction-related deployment descriptors Container-managed persistence generated SQL

Copyright IBM Corp. 2005. All rights reserved.

209

9.1 DB2 locking


Transactional locks within any relational database management system (RDBMS) are a key component in ensuring database integrity. Locks ensure that transactional changes are successfully captured in the RDBMS without being lost by concurrent transactions that reference or manipulate the same data. While locks provide necessary protection, the level of granularity and exclusiveness of locks acquired during a transaction can significantly affect an applications performance and scalability. Designing, developing, and deploying an application to use the optimal granularity of locks is a complex task with many factors. As stated in the introduction, this chapter does not intend to cover every facet of DB2 locking, and as a result many possible locking scenarios are not described. This chapter represents an attempt to review the most common locking scenarios and potential causes of contention. Please see DB2 Universal Database for z/OS Version 8 Administration Guide, SC18-7413, for more details on DB2 locking.

9.2 Transaction isolation


During database access, transaction isolation determines the nature of locks to be acquired, which ultimately determines the transactional integrity. In addition, isolation level is a significant factor in determining whether two separate transactions can read or update the same data and how long the acquired locks will prevent other transactions from performing specific tasks. The affects of transaction isolation can be described as the length of time the lock is held, known as lock duration, and the exclusiveness of the lock, known as the lock mode.

Lock mode
DB2 uses a hierarchy of locks where a single transaction may acquire locks at multiple levels and on multiple objects. The hierarchy differs based upon the table space type the table is created within. Most locking discussions focus on two levels, the first, or least granular being the table space lock (simple or segmented table spaces) or the partition lock (partitioned table space). A subordinate, more granular sized lock is a page (LOCKSIZE PAGE or ANY) or row level (LOCKSIZE ROW) lock. Segmented tables have a third intermediate level of locking, known as table level locks, which we will not discuss since table level locks are generally the result of lock escalatio,n which should be avoided, or an application requesting an explicit table lock. Both of these should not occur within a transactional application environment such as WebSphere. Tip: Table spaces accessed within an online transaction processing environment, such as WebSphere, should use LOCKSIZE ANY or LOCKSIZE ROW. LOCKSIZE TABLE or LOCKSIZE TABLESPACE should be avoided. Partition/table space level locks are most frequently used to show a transactions interest in a particular table while page/row level locks control the access to individual instances of data within the table.

Page and row level lock modes


Page locks and row locks are mutually exclusive options of the DDL table space definition, which determine the type of lock that is used. DB2 stores data in sets of pages, which can vary in size from 4 K, 8 K, 16 K, or 32 K pages. Pages likely contain more then a single row and as a result page level locks have a larger granularity then row level locks. With row level locking, rows that are not intentionally accessed by a transaction can be locked as a result of 210
DB2 for z/OS and WebSphere: The Perfect Couple

page locks being acquired by a transaction. With row level locking, when applications access multiple rows that reside on a page, locks must be successively acquired for each row. Rows and pages have the following locks: S (Share) The lock owner and any concurrent process can read, but not change, the locked page or row. Concurrent processes can acquire S or U locks on the page or row or may read data without acquiring a page or row lock. The lock owner can read, but not change, the locked page or row. Concurrent processes can acquire S locks or might read data without acquiring a page or row lock, but no concurrent process can acquire a U lock. The lock owner can read or change the locked page or row. A concurrent process can access the data if the process runs with UR isolation.

U (Update)

X (Exclusive)

Table 9-1 summarizes the compatibility of page/row locks.


Table 9-1 Compatibility of page and row lock modes Lock mode S U X S Yes Yes No U Yes No No X No No No

Table space, partition, and table lock modes


In addition to the lock modes used by row and page level locks, table space and partition locks also have intent locks. Intent locks indicate that a transaction may intend to acquire a more exclusive lock at a later point in time. Here are the additional intent locks for table space and partition lock modes: IS (Intent Share) The lock owner can read data in the table, partition, or table space, but not change it. Concurrent processes can both read and change the data. The lock owner might acquire a page or row lock on any data it reads. The lock owner and concurrent processes can read and change data in the table, partition, or table space. The lock owner might acquire a page or row lock on any data it reads. It must acquire one on any data it changes. The lock owner can read and change the data in the table, partition, or table space. Concurrent processes can read data in the table, partition, or table space, but not change it. Only when the lock owner changes data does it acquire page or row locks.

IX (Intent Exclusive)

SIX (Shared Intent Exclusive)

Table 9-2 summarizes the compatibility of table space and partition lock modes.
Table 9-2 Lock mode compatibility for table space and partition locks Lock mode S U IS Yes Yes IX No No S Yes Yes U Yes No SIX No No X No No

Chapter 9. DB2 locking in a WebSphere environment

211

Lock mode IS IX SIX X

IS Yes Yes Yes No

IX Yes Yes No No

S Yes No No No

U Yes No No No

SIX Yes No No No

X No No No No

9.2.1 Isolation levels


There are four possible transaction isolation levels applications can exploit when accessing DB2 data. The levels are listed below in order from most to least restrictive. In combination with the executed SQL, these modes determine the lock mode and duration of locks acquired for the transaction. Repeatable Read (RR) Repeatable Read acquires locks on all rows read by an SQL statement whether they qualify for the result set or not. The locks are held until the transaction is ended via a commit or rollback. Other transactions cannot insert, delete, or update rows accessed by an SQL statement executing with RR. Read Stability acquires locks on all stage 1 qualifying rows and maintains those locks until the application issues a commit or rollback. With RS, other transactions cannot update or delete rows that qualified (during stage 1 processing) for the statement, because locks will be held. If the application attempts to re-reference the same data at a later point in the transaction, the results are guaranteed to not have been updated or deleted. However, other applications do have the ability to insert additional rows, this is known as a phantom read, since subsequent selects against the same data within the same transaction may result in additional rows being returned. Cursor Stability insures that all data returned has been committed. Locks are not held for rows/pages for which a cursor is not currently positioned. Locks are also not acquired for non-qualifying rows. If an application attempts to re-reference the same data at a later point in the transaction there is no guarantee that data has not been updated, inserted, or deleted. Locks are not acquired for queries (SELECT), and the application may return data from another transaction that has not yet been committed or rolled back.

Read Stability (RS)

Cursor Stability (CS)

Uncommitted Read (UR)

Isolation modes can be set in multiple fashions including a bind parameter, an explicit method call in JDBC, or within an SQL statement. More information regarding how to set isolation modes is in DB2 isolation determination in Java applications on page 213.

9.2.2 Overriding lock mode


For SQL statements that use the WITH RR or WITH RS option to override the isolation level (as described in SQL statement WITH clause on page 214), an additional option, USE AND KEEP UPDATE LOCKS, USE AND KEEP EXCLUSIVE LOCKS, or USE AND KEEP SHARE LOCKS, can be utilized. These options override the lock mode acquired during standard execution of the SQL statement.

212

DB2 for z/OS and WebSphere: The Perfect Couple

Table 9-3 Lock mode override SQL option USE AND KEEP EXCLUSIVE LOCKS USE AND KEEP UPDATE LOCKS USE AND KEEP SHARED LOCKS DB2 lock mode X U S

By using any of these options, you tell DB2 to acquire and hold a specific mode of lock on all the qualified pages or rows (stage 1 qualified when using RS). All locks are held until the application commits. Although this option can reduce concurrency, it can prevent some types of deadlocks and can better serialize access to data.

9.2.3 DB2 isolation determination in Java applications


There are multiple mechanisms to set the transaction isolation level for an application. Within most non-Java applications, transaction isolation is determined as part of a bind parameter named ISOLATION. With flexibility and platform independence being key components of Java execution environments, JDBC and SQLJ applications have the ability to set isolation levels dynamically via standardized interfaces during both static (SQLJ) and dynamic (JDBC or SQLJ) application execution. In Java applications, the isolation level is an attribute of the database connection, which can be set programatically, or as part of the definition of a datasource from which connections are retrieved.

Connection con.setTransactionIsolation()
A method in JDBC, Connection con.setTransactionIsolation(xxx) allows an application or execution environment to set the transaction isolation for the connection. In SQLJ, the SET TRANSACTION ISOLATION LEVEL statement provides the same functionality. Since you can mix JDBC methods and SQLJ directives within an SQLJ application, both methods will work in an SQLJ application and will affect the isolation of the entire transaction regardless of whether the application switches between JDBC and SQLJ. Transaction isolation should only be set at the beginning of the transaction before any SQL is executed. Restriction: You can only set transaction isolation at the beginning of a transaction. Internally, DB2 manages the multiple isolation levels in a similar fashion to static applications. The JDBC driver uses packages that have been bound with different isolation levels for statements with a transaction isolation. DB2 implements each of the different isolation levels via four versions of JDBC driver packages, each version bound with a different isolation level. When a JDBC application changes the transaction isolation level, the driver is actually dynamically changing JDBC driver packages. Similarly, SQLJ preprocessing produces four versions of an application-specific SQLJ package, generated via the db2sqljcustomize utility. The isolation levels within DB2 do not directly correlate to the isolation levels in the JDBC specification and the isolation levels used in the interface to set the transaction environment. To map the two values, review Table 9-4 on page 214. When calling setTransactionIsolation(), applications specify the JDBC keyword to set the transaction isolation. Note that in a WebSphere environment (prior to WebSphere V5.1) this method is not directly accessible from the application, and should not be exploited (see 9.3.2, Entity Bean isolation level (access intent) on page 218).

Chapter 9. DB2 locking in a WebSphere environment

213

Table 9-4 DB2 UDB for z/OS and JDBC/SQLJ isolation mapping DB2 UDB for z/OS UNCOMMITTED READ (UR) CURSOR STABILITY (CS) READ STABILITY (RS) REPEATABLE READ JDBC/SQLJ /WebSphere TRANSACTION _READ_UNCOMMITED TRANSACTION_READ_COMMITTED TRANSACTION_REPEATABLE_READ TRANSACTION_SERIALIZABLE

Restriction: WebSphere applications (prior to WebSphere V5.1) do not allow the programmatic exploitation of the setTransactionIsolation() method. This method is not promoted to the WebSphere-implemented connection interface. In order to set the transaction isolation level programatically, you must run WebSphere V5.1.

SQL statement WITH clause


The WITH clause allows you to specify an isolation level on an individual SQL statement. This overrides all other forms of setting the isolation level, but offers little flexibility for deploying the same application with different isolation characteristics. The isolation level specified within the SQL WITH clause is the database-specific abbreviation for the isolation level, not the JDBC specification. The WITH statements take the form of WITH UR, WITH CS, WITH RS, and WITH RR, and can only be used in a SELECT statement.

Order of precedence for isolation levels in Java applications


Since there are multiple ways of setting the transactions isolation, it is important to know the precedence order: 1. SQL: WITH <isolation>. 2. Last setTransactionIsolation() on the current connection. 3. WebSphere resource reference value; see Transaction isolation levels on page 218. 4. Default for JDBC in a WebSphere environment. The default is (SQL) Read Stability (JDBC) Repeatable Read. See Transaction isolation levels on page 218 to understand the differences between DB2 and JDBC transaction isolation levels.

9.2.4 Maintaining integrity with isolation Cursor Stability


Most applications do not issue updates without first selecting data to base their updates upon. Frequently the selected data is the same data that will be updated later on in the transaction. To maintain integrity, a mechanism must be in place to ensure that no updates occur between the selection and the update of the data. Failure to prevent an intermediate update can result in a lost update scenario, since the last update to complete does not consider the earlier change in the selected data in its update. Consider two transactions in which each select an integer and then update the integer with the value selected plus one. If one of the transactions updates between the other transactions elect and update, then one of the updates will be lost. Prevention of this must be enforced regardless of how small the timing window is. One mechanism to enforce this integrity is to use a restrictive isolation level, such as RS or RR on SQL SELECT statements. These isolation levels protect integrity by holding locks on selected data from when it was first selected until the end of the transaction. These locks will prevent other applications from updating the data, which can cause a lost update. This approach using a restrictive isolation level can have negative concurrency side effects, especially for rows selected but not subsequently updated within the transaction. 214
DB2 for z/OS and WebSphere: The Perfect Couple

To maintain integrity and exploit isolation cursor stability (CS), applications must use a mechanism beyond the isolation level to ensure that other transactions do not have the opportunity to successfully update data between the time when the data is selected and the target data is updated. This can be accomplished by either using an update cursor or overqualified predicates on an update statement.

Update cursor
Update cursors are commonly used in non-Java applications to process a set of data returned by a query and take some action based upon that returned data. The cursor is used to parse through all of the qualifying rows of a query and update the rows if necessary. While fetching through a cursor, the current row (or page) on which the cursor is positioned is locked and other potential updaters are prevented from updating or deleting the row. While positioned on the row, only the application that is using the cursor can update the row. For example:
DECLARE CURSOR C1 FOR SELECT SALARY FROM EMP WHERE LASTNAME =LEE FOR UPDATE OF SALARY; OPEN CURSOR C1; FETCH FROM C1 INTO :SAL UPDATE EMP SET SALARY = 1000000 WHERE CURRENT OF C1;

In a JDBC application, the declaration and processing of a cursor occur with a different syntax, but the concept is basically the same. Instead of processing a cursor, a PreparedStatement is created and a ResultSet is used to process the results.
PreparedStatemnt p1 = new PreparedStatement(SELECT SALARY, FIRSTNME FROM EMP WHERE LASTNAME = ? FOR UPDATE, TYPE_FORWARD_ONLY, CONCUR_UPDATABL); ResultSet rs = p1.executeQuery(); String s1 = null; String s2 = null; while (rs.next()) { s1 = rs.getString(1); s2 = rs.getString(2); if (s2.compareTo(Sean) == 0) { rs.updateString(s1); rs.updateRow();}

Searched updates with overqualified predicates


A searched update is an UPDATE statement issued against a table with a particular set of predicates that will (normally) reduce the number of rows that are updated. The predicates determine which rows are to be updated, and the SET clause determines the new value. When the predicates limit the update to a single row, this is known as a singleton update. Here is an example of a singleton update (provided there is a unique index on LASTNAME, FIRSTNME):
UPDATE EMP SET SALARY = 1000000 WHERE LASTNAME = LEE and FIRSTNME = SEAN;

As an alternative to using a cursor to guarantee that data has not changed after retrieving it, applications can use an update with additional predicates to ensure integrity. Two approaches are generally used for overqualified predicates, a timestamp, or full predication. For the timestamp approach, a (unique) timestamp column is required on the table, and the timestamp is read with every select, passed to the application with the data to be updated, and then used as a qualifying predicate in the WHERE clause of the update statement. If the update statement returns no rows updated, then the data has been updated since the data was originally selected, and the transaction must be restarted. In addition, update statements must set the timestamp column to the current timestamp (of the update). Frequently the timestamps are defined with default values of the current timestamp. It is worth noting that this method is not fully guaranteed to prevent other updates. It is highly unlikely, but feasible, for two threads to execute within a close enough time to update with the same current timestamp. In order to have unique value, you should use the GENERATE_UNIQUE function
Chapter 9. DB2 locking in a WebSphere environment

215

in DB2 for z/OS Version 8 (or a ROWID defined as GENERATED ALWAYS in earlier DB2 versions). The full predication approach selects all columns within the table and passes all values to the application until the update occurs. When the update occurs, all of the columns in the table are specified as predicates.

Searched updates versus cursor updates


Most Java applications exploit singleton updates (used exclusively in CMPs) to update data. This is a result of the object-oriented nature of Java applications, where the actual update of the data may occur in a different Java method, than the one that was used to select the data. This separation occurs in entity Beans because of the common interfaces used when instantiating a Bean regardless of intent to update or simply reference. In almost all JavaBean cases, the given instance of an object maps to only one row, and there is no need to parse through multiple rows to instantiate an object, thus reducing the benefit of a cursor and favoring a singleton update. The general use of searched updates is also a factor of support in the JDBC specification and in driver implementation to support update through cursors. These feature is a fairly recent enhancement.

CURRENTDATA
CURRENTDATA is a DB2 bind option for ISOLATION(CS) applications, which helps to determine the currency of data returned in a cursor. The JDBC driver is bound with CURRENTDATA(YES) by default. Application developers frequently mistake this option as a mechanism for protecting against the singleton update case, or as a reason to use ambiguous cursors. An ambiguous cursor is a cursor with a select statement that does not express FOR READ ONLY or FOR UPDATE. The CURRENTDATA option has little impact on integrity for these cases. In some specific ISOLATION(CS) applications, if CURRENTDATA(NO) is specified, then DB2 will try not to take a lock, as a result of a DB2 locking optimization technique called lock avoidance. Unfortunately, for isolation CS applications, ambiguous cursors will not provide locks to protect integrity in cases when a work file is exploited. As a result, lock protection for ambiguous cursors are access path dependent. Access paths that exploit a work file cannot be defined as updatable. Application developers should use an additional cursor or overqualified predicates as logically close to the select as possible to reduce the timing window for intermediate updates by other applications. As a rule, regardless of the CURRENTDATA option, isolation CS applications should always express their intent within a cursor and singleton selects should use overqualified expressions to ensure integrity.

9.2.5 Data sharing considerations


Two de facto defaults within WebSphere environments can be particularly painful for DB2 data sharing environments. They are the use of isolation RS or RR, and the use of row level locking. In general, locking within a data sharing environment is more expensive due to the cross-system coordination and communication via the coupling facility. The most efficient lock is the lock not taken. Isolation RS and RR reduce the opportunity for lock avoidance, and generally increase lock duration and the lock mode exclusiveness. Row level locks generally increase the number of lock requests; and, in cases with frequent activity, row locks can result in a serialization of data sharing page P-locks.

216

DB2 for z/OS and WebSphere: The Perfect Couple

To avoid these scenarios, consider the use of isolation CS and the use of MAXROWS 1 with LOCKSIZE ANY to simulate row level locking. This alternative does reduce the number of rows within a page, but it increases the number of getpages, virtual storage/buffer pool utilization, and the number of I/Os. A detailed performance analysis should be completed before implementing this change.

9.3 WebSphere transaction-related deployment descriptors


Since transactions in a WebSphere environment can spawn multiple resources with DB2, transactional attributes are controlled via the application deployment descriptors. While some of the WebSphere deployment descriptors are part of the J2EE standards, many of the descriptors are vendor specific. The following items represent WebSphere-specific deployment descriptors, which control the locking and isolation levels for applications that access relational databases, including DB2.

9.3.1 Setting the WebSphere transaction isolation level


By default, a resource without an explicit setting of the transaction isolation level defaults to JDBC isolation REPEATABLE READ or DB2 isolation READ STABILITY. To set the isolation level for a given datasource, a resource reference can be used. While an application can perform a JNDI lookup for a datasource directly to the datasources name, it is good practice to use a resource reference. When a resource reference is used, the application programmer issues a lookup for java:comp/env/jdbc/T4DBD8 instead of directly accessing the datasource jdbc/T4DBD8 as in Example 9-1.
Example 9-1 Example of a datasource lookup with a resource reference javax.naming.Context ctx = new javax.naming.InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/T4DBD8);

Using a resource reference allows an additional level of indirection between the application and the datasource. This also allows the deployer to set the transaction isolation level for the application in the resource reference. A resource reference is added to the deployment descriptor within the WSAD environments deployment descriptor under the resources tab, as shown in Figure 9-1 on page 218. At execution time, the application looks up this reference (as a result of the java:comp/env, WebSphere knows this to be a reference) and then the reference points to the real datasource. As you can see in the example, the isolation level can also be set for the transaction.

Chapter 9. DB2 locking in a WebSphere environment

217

Figure 9-1 Resource reference isolation settings for session Beans

Transaction isolation levels


The DB2 JDBC driver follows the JDBC specification naming conventions regarding transaction isolation. It is important to note that WebSphere and DB2 naming conventions do not explicitly map. The translation between the two levels is listed in Table 9-4 on page 214.

9.3.2 Entity Bean isolation level (access intent)


The setting of isolation levels in entity Beans differs from all other uses of Beans. CMP entity Beans override all resource reference settings of transaction isolation levels. See 9.4.2, Access intents on page 219, for more details.

9.4 Container-managed persistence generated SQL


One of the main objectives of container-manager persistence entity Beans is to obscure the implementation of persistence behind a convenient J2EE interface to the entity Beans. Frequently, however, the actual implementation of the persistence becomes an important matter for performance and concurrency considerations.

218

DB2 for z/OS and WebSphere: The Perfect Couple

9.4.1 Who generates the persistence SQL


Within WSAD, the target database type is defined during development. This allows entity Beans executing within the development environment to execute against a DB2 UDB for z/OS database server using DB2 UDB for z/OS-specific persistence SQL. During deployment to WebSphere Application Server for z/OS, the persistence code is usually regenerated for deployment. Assuming the WSAD environment and the target execution environment are at functionally equivalent maintenance levels, the resulting SQL statements will generally be identical.

9.4.2 Access intents


As part of WebSpheres extension to the EJB specification, WebSphere allows you to specify the access intent of an entity Bean. This intent, only available for entity Beans, allows the application deployer to indicate how the Bean will be referenced, which will affect the locks used for persistence and the isolation level. wsPessimisticUpdate-WeakestLockAtLoad A value of update indicates that the caller intends to drive update methods on the entity Bean. This policy obtains a weak lock on the load (WebSphere Default). A value of update indicates that the caller intends to drive update methods on the entity Bean. This policy locks tables or rows being updated in the SQL statement. A value of read indicates that the caller does not intend to drive an update method on the entity Bean. This policy locks tables or rows being read in the SQL statement. A value of update indicates that the caller intends to drive update methods on the entity Bean. This policy uses overqualified predicates to check for updates that have occurred since the last READ. A value of read indicates that the caller does not intend to drive an update method on the entity Bean. This policy does not lock the database. Specifies that the application will have no row collisions by design. Specifies that the application prefers exclusive access to the database rows.

wsPessimisticUpdate

wsPessimisticRead

wsOptimisticUpdate

wsOptimisticRead

wsPessimisticUpdateNo-Collisions wsPessimisticUpdate-Exclusive

Each of these access intents results in different SQL being generated for the entity Bean persistence code. For CMP Beans, isolation level is specified as part of the SQL statements within the persistence and retrieval methods for the Bean. A summary of the appendages to the persistence code for each access intent is listed in Table 9-5 on page 220.

Chapter 9. DB2 locking in a WebSphere environment

219

Table 9-5 Access Intent SQL append summary


Access intent profile DB2 UDB for z/OS isolation Read Stability (RS) JDBC isolation FOR UPDATE append? NO

wsPessimisticUpdateWeakestLockAtLoad (Default policy) wsPessimisticUpdate

TRANSACTION_REPEATABLE_READ

Read Stability (RS)

TRANSACTION_REPEATABLE_READ

YES

wsPessimisticRead

Read Stability (RS)

TRANSACTION_REPEATABLE_READ

NO

wsOptimisticUpdate wsOptimisticRead wsPessimisticUpdateNoCollisions wsPessimisticUpdateExclusive

Cursor Stability (CS) Cursor Stability (CS) Cursor Stability (CS)

TRANSACTION_READ_COMMITTED TRANSACTION_READ_COMMITTED TRANSACTION_READ_COMMITTED

NO NO NO

Repeatable Read (RR)

TRANSACTION_SERIALIZABLE

YES

wsOptimisticUpdate
This access intent has the benefit of allowing isolation CS access to tables to ensure integrity. As described in Searched updates with overqualified predicates on page 215, this access intent generates persistence SQL with overqualified predicates to ensure integrity between selects and updates of the data. The full predicate option is used during the update to ensure that there is no integrity exposure since the data selection methods and data update methods do not pass a cursor or maintain locks. There is a limitation within the WebSphere persistence code regarding the over qualification of predicates. Columns within the table that are nullable are not included in the overqualified predicate list. As a result, data integrity exposures can occur if another application updates the columns that are nullable. It is generally not recommended to use nullable columns in Java applications, but the opportunity for data loss does exist and application developers should be aware of this restriction. Important: Use of wsOptimisticUpdate and nullable columns can result in a data integrity exposure and data loss. Do not use wsOptimisticUpdate on tables that contain any nullable columns.

220

DB2 for z/OS and WebSphere: The Perfect Couple

10

Chapter 10.

DB2 - WebSphere performance aspects


Performance tuning in a WebSphere - DB2 for z/OS environment is a complex exercise. The nature of the run time involves many different components of the operating system and middleware. DB2 performance is critical to the overall performance of WebSphere for z/OS applications. In this chapter we focus on topics related to DB2 in a WebSphere Application Server for z/OS environment. These topics include: Recommended hardware and software configuration WebSphere Application Server connection pooling for z/OS DB2 and JDBC Workload Management (WLM) classification of WebSphere Application Server and its impact on DB2 Tuning the storage for z/OS and Java Virtual Machine (JVM) For additional information on DB2 tuning refer to DB2 Universal Database for z/OS Administration Guide Version 8, SC18-7413. For tuning and monitoring tasks in WebSphere Application Server for z/OS, see IBM WebSphere Application Server for z/OS V5.0.2 Performance Tuning and Monitoring, SA22-7962.

Copyright IBM Corp. 2005. All rights reserved.

221

10.1 Recommended hardware and software configuration


To best utilize current technology resources, the following configuration is recommended when running WebSphere Application Server for z/OS. Hardware configuration A 9672 G5 or the later zSeries is strongly recommended. IEEE floating point, which is commonly used in Java, is emulated on the earlier machines. z990 machines deliver superior performance via higher CPU processing speed, IEEE floating point, cryptography hardware, the Integrated Cryptographic Service Facility, and new hardware instructions. Java workloads require more storage than traditional workloads. The virtual storage default should be about 370 MB per servant, which includes a 256 MB default heap size and a default LE heap size of 80 MB. The minimum real storage requirement is 512 MB per LPAR for a light workload, such as the IVP or a sandbox system. For more real-world applications, we recommend 2 GB or higher.

Cached DASD. To maximize your performance, we recommend a fast DASD subsystem, for example, IBM Enterprise Storage Server (also known as Shark), running with a high cache read/write hit rate. OSA Express on zSeries 990. For high-bandwidth applications, we recommend at least a one gigabit Ethernet connection. If your applications have extremely high bandwidth requirements, you may need additional Ethernet connections. Software configuration In general, the latest software levels with the most recent PTFs applied perform best. In a WebSphere - DB2 environment this means: WebSphere Version 5.0.2 Statement cache enhancement New JDBC Providers support (DB2 Universal Driver) Customizable Performance Monitoring Infrastructure (PMI) Deferred Write operations for EJB 2.0 CMPs

Java SDK 1.3.1 DB2 and JDBC Drivers Version 8 IBM DB2 Universal Driver for SQLJ and JDBC Unicode support DDF communication database enhancements Enhancements for stored procedures and UDFs

z/OS Release 5

10.2 WebSphere Application Server connection pooling


Connection pooling can improve the response time of any application requiring connections to access a data source, especially Web-based applications. To avoid the overhead of acquiring and closing connections, WebSphere Application Server provides connection pooling for connection reuse (caching of JDBC connections). WebSphere Application Server enables administrators to establish a pool of database connections that can be reused. In certain situations the connections can be shared by applications on a datasource or connection factory to address these overhead issues. 222
DB2 for z/OS and WebSphere: The Perfect Couple

10.2.1 What is new in Version 5 - What is in WebSphere Version 4


Connection pooling in WebSphere Application Server for z/OS Version 4 makes use of the DB2 legacy JDBC Driver connection pooling support. In Version 4, you can enable JDBC connection pooling by setting the following parameter in the J2EE servers jvm.properties file:
com.ibm.ws390.ConnectionUsageScopeDefault=SeriallyReusable

WebSphere Application Server for z/OS Version 5 has its own connection pooling. The connection pooling support for z/OS in V5 is consistent with other WebSphere platforms. Support for the new DB2 Universal JDBC Driver (sometimes referred to as DB2 JCC Driver) is provided in WebSphere for z/OS Release 5.02 with PTF level W502002. As discussed in 3.2, Introduction to DB2 drivers for Java on page 50, the following new JDBC providers have been included in the JDBC provider selection list when using the Administrative Console application: DB2 for z/OS Local JDBC Provider (RRS) The DB2 for z/OS Local JDBC Provider (RRS) option replaces the previous DB2 390 Local JDBC Provider (RRS) option. DB2 for z/OS Local JDBC Provider (RRS) supports the creation of WebSphere Application Server V5.0 data sources and V4.x level data sources. This provider is also referred to as DB2 Legacy JDBC Driver. DB2 Universal JDBC Driver Provider This is a non-XA JDBC provider. The JCC driver supports both type 2 and type 4 drivers. Transaction processing using type 4 connectivity is performed using one-phase commit. Transaction processing using type 2 connectivity utilizes Resource Recovery Services (RRS) to coordinate transactions with two-phase commit or one-phase commit. DB2 Universal JDBC Driver Provider supports the creation of both WebSphere V4.x and V5.0 data sources. DB2 Universal JDBC Driver Provider (XA) This is an XA JDBC provider with type 4 connectivity. The J2EE XA transaction architecture is supported by the Universal JDBC Driver under this provider. This permits the coordination of XA transactions across multiple resources using two-phase commit processing. Note: DB2 Universal JDBC Driver Provider (XA) only supports creation of the WebSphere V5.0 data sources, and not the creation of WebSphere V4.x level data sources.

10.2.2 How connection pooling works - How connection objects are structured
A unique Java Naming and Directory Interface (JNDI) name is needed to configure a unique data source or connection factory. A connection pool is created based on the JNDI name and its configuration information. A separate connection pool exists for each configured data source or connection factory. Connections can only be shared by applications if the connections are obtained from the same pool. The connections, out of the same pool, are not shared automatically. Sharing happens only under certain conditions (that is, the connection properties are the same).

Chapter 10. DB2 - WebSphere performance aspects

223

For illustration purposes, connection objects can be in one of three states (see Figure 10-1). Does Not Exist In Free Pool In Use Before a connection is created, it is in the Does Not Exist state. After the connection is created, and has not been allocated to an application. The connection is allocated to an application, and currently active.

A connection leaves the In Use Pool when the connection is closed. This could mean an application closes the connection, or a transaction involving shared connections has ended. When a connection is closed by an application, one of the following can happen: The connection will move to the Does Not Exist state if and only if the connection is stale. An un-shareable connection will return to the In Free Pool. A shareable connection will move to the In Free Pool if the connection is not being used by other connection handles (that is, the transaction has ended). A shareable connection may stay in the In Use state if the connection is being used by other connection handles. When sharing connection handles across transaction boundaries, the physical connection (managed connection) may stay in the In Use state even when the transaction is done. Once the handle is touched again (used again), the connection handle will be associated with another similar managed connection, which may or may not be the same managed connection as before, but must have the same properties. Connections move from the In Free Pool state to the Does Not Exist state only during pool maintenance. Pool maintenance runs are based on the Reap Time value set for the connection pool. For more information on Reap Time, see Reap Time on page 225.

Connection Pool
Connection Tim eout Unused Tim eout

Does Not Exist

Reap Tim e

In Free Pool
Aged Tim eout

In Use
Connection properties - Transaction ID - JNDI nam e - Resource authentication - Isolation level (access intent)

Figure 10-1 State of a connection object

10.2.3 WebSphere data sources


The following areas have a large performance impact in determining datasource queues: Max Connections Min Connections 224
DB2 for z/OS and WebSphere: The Perfect Couple

Sh ar ed

Reap Time Timeout Connection Timeout Aged Timeout Unused Timeout Purge Policy Statement cache size

Max Connections
The Max Connections parameter specifies the maximum number of physical connections that can be created in the pool. Once this number is reached, no new physical connections are created and the requester waits until a connection that is currently in use returns to the pool, or a ConnectionWaitTimeoutException is thrown. For example, if the Max Connections value is set at 10, and there are ten physical connections in use, the pool manager waits for the amount of time specified in Connection Timeout for a physical connection to become free. If a physical connection is not available within the Connection Timeout interval, the pool manager throws a ConnectionWaitTimeoutException. If Max Connections is set at 0, it means there is no limit to the number of physical connections in the pool. The Connection Timeout value is ignored. Better performance can be achieved if you: Set the maximum connection pool value lower than the value for the Max Connections in the Web container. Consider the number of Central Processors (CPs) in your environment. The maximum connection pool setting should be lower when there are fewer CPs for WebSphere. In general, lower settings (1030 connections) perform better than higher settings (100 or greater). The default setting, 10, is a good starting point. Realize each entity Bean transaction requires an additional connection to the database to handle the transaction. Consider this when calculating the maximum/minimum number of connections.

Min Connections
The Min Connections parameter specifies the minimum number of physical connections that need to be maintained. Until this number is reached, the pool maintenance thread does not discard physical connections. However, no attempt is made to bring the number of connections up to the minimum. If you set a value for Aged Timeout (defined later), the minimum is not maintained. All connections with an expired age are discarded. Set the minimum number in accordance to your environmental needs. The default setting is 1.

Reap Time
The Reap Time parameter defines the interval, in seconds, between runs of the pool maintenance thread. For example, if Reap Time is set to 60, the pool maintenance thread runs every 60 seconds. The Reap Time interval affects the accuracy of the Unused Timeout and Aged Timeout settings. The smaller the interval, the greater the accuracy. When the pool maintenance thread is invoked, it moves the following connections from the In Free Pool to the Does Not Exit state: Connections whose Unused Timeout is expired if the pool contains more than the minimum connections. Connections whose Aged Timeout is expired.

Chapter 10. DB2 - WebSphere performance aspects

225

The Reap Time interval also affects performance. Smaller intervals mean the pool maintenance thread runs more often, degrading performance. Set the Reap Time lower than the Unused Timeout and Aged Timeout intervals for optimal performance. The pool maintenance thread can be disabled by setting the Reap Time to 0. In that case, the Unused Timeout and Aged Timeout parameters are ignored.

Connection Timeout
The Connection Timeout parameter defines the interval, in seconds, after which a request for connection times out, and a ConnectionWaitTimeoutException is thrown. The wait is necessary when the pools maximum number of connections have been reached. For example, If Connection Timeout is set to 180 and the maximum number of connections is reached, the pool manager waits for 180 seconds for an available physical connection. If a physical connection is not available within this time, the pool manager throws a ConnectionWaitTimeoutException. If Connection Timeout is set to 0, the pool manager waits as long as necessary (potentially forever) until a connection can be allocated. If Max Connections is set to 0, it means there is no limit for physical connections in the pool, and the Connection Timeout value is therefore ignored.

Aged Timeout
The Aged Timeout parameter defines the interval, in seconds, before a physical connection is discarded. Setting Aged Timeout to 0, which is the default, supports physical connections remaining in the pool, at the In Free Pool state, indefinitely. Set the Aged Timeout higher than the Reap Time interval for optimal performance.

Unused Timeout
The Unused Timeout parameter defines the interval, in seconds, after which an unused or idle connection is discarded. Physical connections in the In Free Pool state are discarded only if these connections are higher than the minimum connections. Set the Unused Timeout higher than the Reap Time interval for optimal performance.

Purge Policy
The Purge Policy parameter defines how to purge connections when a stale connection or fatal connection error is detected. The valid values are: EntirePool All connections in the pool, including connections for both In Use and In Free Pool, are marked stale. Connections in the In Free Pool state are closed immediately. Connections in the In Use state are closed, and a StaleConnectionException is thrown during the next operation on that connection. New getConnection requests from the application result in new connections to the database. A purge policy of the EntirePool offers the safest choice. FailingConnectionOnly Only the connection involved with the StaleConnectionException is closed. There is no guarantee that the rest off the connections in the pool are all valid. Therefore, application recovery becomes more complicated. 226
DB2 for z/OS and WebSphere: The Perfect Couple

You can specify these parameters via the Connection Pools option of the datasource via the Administrative Console. Click Resources JDBC Providers DB2 Universal JDBC Driver Provider Data Sources ITSO1 Connection Pools (Figure 10-2).

Figure 10-2 Connection pool parameter specification

Statement cache size


The statement cache size indicates the number of free statements that are cached per connection. Caching of prepared statements improves Web-based application response times. The WebSphere Application Server data source optimizes the processing of prepared statements. A prepared statement is a precompiled SQL statement that is stored in a prepared statement object. When these cached JDBC prepared statement objects are reused, they avoid the JDBC Driver overhead that is needed for creating a new prepared statement object. If the cache is not large enough, useful entries could be discarded to make room for new entries. Generally, the more statements your application has, the larger the cache should be. For example, if the application has five SQL statements, set the statement cache size to 5, so that each connection has five statements. DB2 dynamic statement caching further enhances WebSphere statement caching. See 10.3.2, Enabling DB2 dynamic statement cache on page 229, for more details.

Chapter 10. DB2 - WebSphere performance aspects

227

As always, you specify the statement cache size for a datasource via the Administrative Console. Click Resources JDBC Providers DB2 Universal JDBC Driver Provider Data Sources ITSO1 (Figure 10-3).

Figure 10-3 Statement cache size

10.2.4 Connection pooling - Best practices


To get the most out of connection pooling, consider the following recommendations: If an application creates a resource, the application should explicitly close it, once the resource is no longer being used. All JDBC resources that have been obtained by an application should be explicitly closed by the same application. These include connections, CallableStatements, PreparedStatements, ResultSets, and others. Be sure to close resources even in the case of a failure. For example, each PreparedStatement object in the cache can have one or more result sets associated with it. If a result set is opened and not closed, even though you close the connection, that result set is still associated with the prepared statement in the cache. Each of the result sets has a unique JDBC cursor attached to it. This cursor is kept by the statement and is not released until the prepared statement is cleared from the WebSphere Application Server cache. Obtaining and closing the connection in the same method. When possible, we recommend that an application obtains and closes its connection in the same method in which the connection is requested. This keeps the application from 228
DB2 for z/OS and WebSphere: The Perfect Couple

holding resources that are not being used, and leaves more available connections in the pool for other applications. Additionally, it removes the temptation to use the same connection for multiple transactions. Of course, there may be times in which this is not feasible, such as when using BMP. Do not reuse the statement handle without closing it first. To prevent resource leakage, close prepared statements before reusing the statement handle to prepare a different SQL statement with the same connection. Do not manage data access in Container Managed Persistence (CMP) Beans. The reason for using a CMP Bean is to hide the details of the data access. By default, users of CMPs cannot manage their own data access. If a CMP Bean is written to manage its own data access, this data access may become part of a global transaction. It is certainly necessary to pay attention to the transaction requirements of each method to achieve data integrity and business objectives. If a user needs more fine-grained control over the details of their data persistence, then they should use Bean-Managed Persistence Beans (BMPs) instead of CMPs. Finally, it is also possible for the user to perform data access functions in session Beans and servlets.

10.3 DB2 and JDBC


In this section we cover some topics related to DB2-specific parameters and settings that can affect the performance of your applications running in a WebSphere Application Server environment.

10.3.1 Adjusting the number of DB2 threads and connections


The WebSphere connection pool settings (see 10.2, WebSphere Application Server connection pooling on page 222) are directly related to the number of connections that have to be configured in DB2 to support this. Knowing the number of data pools is also important when configuring the databases maximum connections. You set the limit of the number of allied and database access threads that can be allocated concurrently using the MAX USERS and MAX REMOTE ACTIVE fields on installation panel DSNTIPE. You should adjust the following DSNZPARM parameters according to your machine size, your virtual and real storage, your workload, and the number of WebSphere connection that are needed. MAX USERS (CTHEAD) specifies the maximum number of allied threads, threads started at the local subsystem, that can be allocated concurrently. These threads are for local requests such as type 2 JDBC users. MAX REMOTE ACTIVE (MAXDBAT) specifies the maximum number of database access threads (DBATs) that can be active concurrently. These threads are for connections coming into DB2 through DDF, such as DRDA, Private protocol connections, as well as remote requests via the DB2 Universal Driver using type 4 connectivity. MAX REMOTE CONNECTED (CONDBAT) specifies the maximum number of inbound connections for database access threads.

10.3.2 Enabling DB2 dynamic statement cache


The WebSphere statement cache function works together with DB2 dynamic statement caching. When the prepared statements are cached in the EDM pool (DSNZPARM CACHEDYN=YES), re-calculation of the access path can be avoided if the statement in the DB2 dynamic statement cache can be reused by a subsequent execution. This saving is in
Chapter 10. DB2 - WebSphere performance aspects

229

addition to saving the JDBC precompiled SQL cost that WebSphere statement caching (caching the prepared statement object) offers. The following DB2 system parameters (in DSNZPARM) should be reviewed: CACHEDYN = YES means the DB2 global dynamic statement cache is enabled. MAXKEEPD specifies the maximum number of SQL statements kept in the local statement cache. (This parameter only applies to applications that also use the KEEPDYNAMIC(YES) bind option.) EDMPOOL specifies the size of the EDM pool. If you store the statements from the global dynamic statement cache in the EDM pool, you may have to adjust the size (make it bigger) to allow for those statements. Otherwise, you may end up pushing out other objects (SKPTs, SKCTs, and DBs) from the EDM pool. EDMDSPAC and EDMDSMAX (V7) specify that the statements in the global dynamic statement cache will not reside in the EDM pool, but in a separate data space. EDMDSPAC specifies the startup value, whereas EDMDSMAX specifies the maximum size the data space can be changed to via the -SET SYSPARM command. EDMSTMTC (V8) specifies the size of the global dynamic statement cache. The global dynamic statement cache resides above the 2 GB bar in V8. In V8, the global dynamic statement cache is always in a separate storage area from the EDM pool.

10.3.3 Choosing static SQL over dynamic SQL


Today, the Java world uses dynamic SQL (JDBC) more frequently then static SQL (SQLJ). One of the major factors for not using SQLJ was the limited SQLJ support by application development tools. WebSphere Studio Application Developer (WSAD) V5.1.2 will fully support connections to DB2 for z/OS V8. Previous versions of WSAD supported connections to DB2 for OS/390 V7 and V6. So, from the application development point of view, there are no more excuses not to use SQLJ. From the performance point of view, SQLJ and its static SQL implementation by DB2 brings major performance benefits for SQLJ compared to JDBC. SQLJ packages offer consistent performance and give better capacity control of the environment. SQL statements are recorded in the DB2 catalog. SQL access paths are pre-bound for each SQL statement, and not determined at run time. Access paths do not change until the next REBIND. EXPLAIN data can be saved during program deployment. SQLJ packages make performance monitoring and management easier. Performance monitoring (for example, CPU time, I/O operations, getpages, etc.) is at the program/package level when using SQLJ. Package names are visible to online monitor tools (DB2 Performance Expert, Omegamon, etc.), making it easier to identify performance bottlenecks.

10.3.4 Usage guidelines for JCC type 2 and type 4 connectivity


DB2 Universal Driver support for applications running in WebSphere Application Server is only available with level W502002. Applications running in WebSphere V5.02 (W502002) can use either type 2 or type 4 connectivity when accessing DB2 V7 or DB2 V8 back-end databases.

230

DB2 for z/OS and WebSphere: The Perfect Couple

Performance considerations
Which connectivity type gives the best performance? Type 2 or type 4 connectivity? Tests conducted by the Silicon Valley Labs performance experts concluded the following: When accessing DB2 V7 or DB2 V8 back-end databases that reside on the same z/OS system image (LPAR) that the application is running on, type 2 connectivity provides better throughput and CPU utilization than type 4 connectivity. This is due to the network overhead. The JCC type 4 driver is implemented using the DRDA protocol over a TCP/IP network connection. Applications accessing local databases residing on the same z/OS system image using the JCC type 2 driver do not need to go over a TCP/IP network link. This is true even if the TCP/IP connection does not really need to go out on a physical network link. The fact that we need to go through additional layers (TCP/IP and DDF) introduces CPU and elapsed time overhead that can be avoided when using a local attachment via the JCC Type 2 driver (see Figure 10-4).

C e ll Y
M STR

z/OS Image

IR L M DBM1

D aem on
Node X

S to re d S t o rP er d ocs P ro c s

DDF

T2

A p p S e rve r

Figure 10-4 Using type 2 connectivity for local DB2 access

When accessing DB2 V7 or DB2 V8 back-end databases residing on a different z/OS system image (remote databases) than the application (WebSphere), type 4 connectivity (see Figure 10-5) achieved significant performance improvements over using type 2 connectivity to a local DB2 system, whos DDF DRDA Application requester function is used to communicate with the remote DB2 (illustrated in Figure 10-6 on page 232).

Cell Y

z/OS Image A

Daemon
IRLM DRDA / TCPIP

DBM1

Node X

Stored Stored Procs Procs

AppServer
T4 XA

DDF

Figure 10-5 Connecting a WAS to a DB2 for z/OS via the type 4 XA Universal Driver

The configuration shown in Figure 10-5 is also known as z/OS Application Connectivity to DB2 for z/OS and OS/390, or the type 4 XA driver. It is a separately orderable, no-charge feature of DB2 for z/OS and OS/390 Version 7 and DB2 for z/OS Version 8.

z/OS Image B
231

MSTR

Chapter 10. DB2 - WebSphere performance aspects

Cell Y

z/OS Image A

MSTR

Daemon

DBM1

IRLM

IRLM DDF

DBM1

Stored Stored Procs Procs

Node X
Stored Stored Procs Procs

DDF

AppServer
T2

Figure 10-6 Connecting a WAS to a DB2 for z/OS via a DB2 router system and a type 2 driver

10.3.5 Enterprise JavaBeans (EJBs) and DB2 access


Below is a list of performance considerations when using EJBs to access DB2 data: Stateless session Beans have the lowest overhead if the Bean does not access a data store. They are inexpensive to create; and, if not cleared up by the application, will disappear when the server terminates. If the configuration purpose is to store the Bean state in memory, remember that stateful session Beans have slightly more overhead than stateless Beans. If the configurations purpose is to store the Bean state in a data store at the end of each transaction, the data store overhead could be more than when using memory. Generally, well-implemented BMP Beans perform better than CMP Beans because you know your application needs. Therefore, applications can have more fine-grained control over the details of the data persistence. However, CMP Beans should get better over time and CMP Beans are easier to maintain. Consider using local transactions when appropriate. Generally, local transactions are the fastest. Use transactional attributes TRANSACTION_NOT_SUPPORTED or TRANSACTION_SUPPORTS if transactional behavior is not required. (For more information on how to specify transactional attributes, see 8.2.3, Transaction types (for container-managed transactions) on page 196.) Fetch only the data that is needed from DB2. Limit both the number of rows and the number of columns that are retrieved. Be aware that CMP Beans always select all columns. Use positional iterators rather than named iterators when using SQLJ. Use prepared statements to allow use of dynamic statement cache in both WebSphere and DB2 for z/OS. Do not include literals in the prepared statements. Use a parameter marker (?) to allow the use of dynamic statement cache of both WebSphere and DB2 on z/OS.

10.4 WLM classification of WAS and its impact on DB2


Similar to WebSphere Application Server Version 4, Version 5 uses Workload Management (WLM) to manage the performance of the application server region(s) in a z/OS environment.

232

DB2 for z/OS and WebSphere: The Perfect Couple

z/OS Image B

MSTR

10.4.1 How DB2 and WebSphere Servers are structured on z/OS


WebSphere applications are deployed within a WebSphere server or a cluster of servers. Each server process consists of a controller region and one or more servant regions. The controller regions are started by the Deployment Manager, or by a z/OS operator command as z/OS started tasks. The servant regions are started by WLM as needed (Figure 10-7).

MSTR DBM1

Daemon
IRLM

Cell Y AppServer
Controller

Node X

Servant Servant Servant

Stored Stored Procs Procs

AppServer
DDF

Figure 10-7 WebSphere Application Server configurations

10.4.2 Enabling WLM dynamic application environments with WAS V5


WebSphere for z/OS uses WLM application environments to operate servant regions. With recent functional enhancements to WLM, application environments can either be dynamic or static. If you are running z/OS Version 1.2 or later, you may choose to use dynamic application environment. With this option WebSphere users do not need to define application environments through WLMs administrative application (the TSO panels). In this case, the WebSphere controller region creates a dynamic application environment with a scope of system when it starts up. The dynamic application environment is not supported in WebSphere Application Server Version 4.x. WLM APAR OW54622 (for z/OS Releases 2, 3, and 4) delivers the dynamic application environment function. PTFs have been available since May, 2003. The dynamic application environment can be enabled through the Administrative Console application. Use the Administrative Console to provide both the JCL procedure name and the JCL parameters for the servant. The related WebSphere environment variables are: server_region_dynapplenv_jclproc = <servant region procedure name> When dynamic application environment is being used, this variable specifies the name of the JCL procedure for a servant region, when WLM starts this servant region. It can be specified using the Administrative Console via Servers Application Servers server-name Process Definition Servant startCommand. server_region_dynapplenv_jclparms = JOBNAME=&IWMSSNM.S,ENV=<cell_short_name>,<node_short_name>.&IWMSSNM When dynamic application environment is being used (instead of the same content existing in static definitions of WLM panels), this variable specifies the JCL parameters provided to the servant region when WLM starts this servant region. It can be specified using the Administrative Console via Servers Application Servers server-name Process Definition Servant startCommandArgs.

10.4.3 WebSphere classification and its impact on DB2


Setting the WLM goals properly can have significant effects on application throughput. As mentioned before, WebSphere for z/OS uses WLM application environments to operate

Chapter 10. DB2 - WebSphere performance aspects

233

servant regions. The WebSphere for z/OS system address spaces and DB2 address spaces should be given a fairly high priority. As work comes into the system, the work classification of the enclaves should be based on your business goals. Set up service classes with a velocity goal for the following address spaces: Daemon and controller address spaces should be classified so they get assigned the SYSSTC service class. By default, address spaces for VTAM, TCP/IP, and IRLM are also classified as SYSSTC. These address spaces should always have a higher dispatching priority than the DBMS and WebSphere servant address spaces. Servant address spaces should be classified as a high STC importance service class. The velocity goals for WebSphere servant regions are only important during startup or restart. After the transactions begin running, WLM ignores the WebSphere servants velocity goals, and assigns a priority based on the goals of transactions that are running in the servant regions. The services class assigned to the transaction will also determine the WLM goal for other work such as the work done inside the DB2 address spaces. The service class of the WebSphere transactions should not have a higher importance than the DB2 address spaces. Similarly, when you set response time goals for DDF threads or for WLM established stored procedures, the only work controlled by the DDF or stored procedure velocity goals is the work performed for DB2 that cannot be attributed to a users transaction. The users work runs under separate goals for the enclave. The WLM application environment is used for work running under servants. The work can be classified based on server name, server instance name, user ID, and transaction classes (that you can set up yourself). WLM uses subsystem type CB for WAS work. Percentage response time goal is recommended. It is usually a good idea to make the goals achievable. For example, a goal that 80 percent of the work will complete in .25 seconds is a typical goal. Velocity goals for application work are not meaningful and should be avoided.

10.5 Tuning the storage for z/OS and the Java Virtual Machine
WebSphere for z/OS has much higher demands on virtual memory than a traditional workload. Since real storage is needed to back virtual storage, the real storage usage is also high. Therefore: Allocate enough virtual storage. Specify REGION=0M in the JCL procedures that are used to run servant regions. This parameter tells the operating system to give all the available storage to the region. Allocate enough real storage. For controllers and servants, real storage utilization depends on the size of the Java Virtual Machine (JVM) heapsize. Recommendation: In a large and heavily used environment, 2G of central storage may not be enough to handle the real storage demands of high-volume Java applications. You may need to consider running in 64-bit mode (ESAME mode or z/Architecture mode). Running in 64-bit mode gives you the ability to define more than 2 GB of central storage. This option is available for zSeries machines that run OS/390 V2R10 or later. Tune the size of JVM heap size. Specifying sufficient JVM heap size is important to Java performance. The JVM has thresholds it uses to manage the JVMs storage. When these thresholds are reached, the garbage collector (GC) is invoked to free up unused storage. Garbage collection can cause significant degradation of Java performance.

234

DB2 for z/OS and WebSphere: The Perfect Couple

It is good for the Initial Heap Size to equal the Maximum Heap Size because it allows the allocated storage to be completely filled before GC kicks in. If not, GC will run more frequently than necessary, potentially impacting performance. Make sure the region is large enough to hold the specified JVM heap. Beware of making the Initial Heap Size too large. While it initially improves performance by delaying garbage collection, it ultimately affects response time when garbage collection eventually kicks in (because it runs for a longer time). Paging activity on your system must also be considered when you set your JVM heap size. If your system is already paging heavily, increasing the JVM heap size might make performance worse rather than better. To determine if you are being affected by garbage collection, you can enable Verbose Garbage Collection on the JVM Configuration tab. The default is not enabled. This will write a report to the output stream each time the garbage collector runs. This report should give you an idea of what is going on with Java GC. The default of 256M is a good starting point. However, it may need to be raised for larger applications. The Java heap size should be monitored. Run with the Just In Time (JIT) compiler active. Make sure the Disable JIT is not selected in the General Properties section of the Configuration Tab. The default is JIT enabled. Do not specify the debug version of the JVM libjava_g in your LIBPATH. Performance degradation occurs when running with the debug version of the JVM. Make your CLASSPATH efficient. Only point to the classes you need, and place the frequently referenced classes first.

10.6 Universal Driver tracing


In this section we briefly describe a few options that you have at your disposal to do tracing using the Universal Driver. We focus on: The Universal Driver trace The DB2Systemmonitor class

10.6.1 Universal Driver tracing


A very useful feature of the DB2 Universal Driver for SQLJ and JDBC is its tracing support, which can be turned on, either from within your program, or even externally by setting up properties on the DataSource definition, or in the JDBC connection URL. This way, you can turn on tracing even when running an application for which you do not have the source code, provided that the connection URL is specified externally to the program. In this section we focus on tracing in a WebSphere Application Server environment, without changing the program itself. These techniques allow us to enable/disable tracing without having to make any change to the program. This is particularly important when using packaged applications where you do not have the source code. For information on how to turn on tracing inside the program, see Chapter 14, Error handling and diagnosis, in DB2 for z/OS and OS/390: Ready for Java, SG24-6435. For more information on how to turn on tracing outside the program for a stand-alone Java application, see Enable tracing on the Universal Java client without changing the application on http://www.ibm.com/support/. Use 7005620 as a search argument for easy retrieval.

Chapter 10. DB2 - WebSphere performance aspects

235

Trace levels
Table 10-1 lists the available trace levels for the Universal Driver. The constants representing these levels are declared in class com.ibm.db2.jcc.DB2BaseDataSource. You can combine individual levels using bitwise OR operations.
Table 10-1 Trace level options for the DB2 Universal Driver for SQLJ and JDBC Constant name TRACE_NONE TRACE_CONNECTION_CALLS TRACE_STATEMENT_CALLS TRACE_RESULT_SET_CALLS TRACE_DRIVER_CONFIGURATION TRACE_CONNECTS TRACE_DRDA_FLOWS TRACE_RESULT_SET_META_DATA TRACE_PARAMETER_META_DATA TRACE_DIAGNOSTICS TRACE_SQLJ TRACE_XA_CALLS TRACE_ALL Dec value 0 1 2 4 16 32 64 128 256 512 1024 2048 -1 Hex value 0x0000 0x0001 0x0002 0x0004 0x0010 0x0020 0x0040 0x0080 0x0100 0x0200 0x0400 0x0800 0xFFFFFFFF

Usually, TRACE_DRDA_FLOWS should be turned off since it generates a lot of output. For example, to enable all trace levels except TRACE_DRDA_FLOWS, you could simply code ~TRACE_DRDA_FLOWS (~ is the bitwise NOT operator in Java).

Driver-wide tracing
To trace the activity of all connections using the Universal Driver, you can use specifications in the DB2 Universal Driver global properties file. (This is the same file where you specify the local DB2 subsystem name for type 2 connectivity.) As with most things in a Java world, there a many different ways to set configuration properties. The easiest way is probably to put them in a normal file, and set up the db2.jcc.propertiesFile Java system property that points to that file. The following driver configuration properties are related to tracing: db2.jcc.traceFile Enables the Universal Driver to trace for Java driver code, and specifies the name of the file on which the trace file names will be based. You can specify a fully qualified z/OS UNIX System Services file name for the db2.jcc.traceFile property value. For most properties there is a way to override any existing values at the Connection or DataSource level. The db2.jcc.override.traceFile property overrides any traceFile property value that might have been specified for a Connection or DataSource object. (If the configuration property begins with db2.jcc.override, the configuration

db2.jcc.override.traceFile

236

DB2 for z/OS and WebSphere: The Perfect Couple

property is applicable to all connections and overrides any Connection or DataSource property with the same property name. If the configuration property begins with db2.jcc or db2.jcc.default, the configuration property value is a default. Connection or DataSource property settings override that value.) db2.jcc.t2zosTraceFile Enables the Universal Driver trace for C/C++ native driver code for type 2 connectivity, and specifies the name on which the trace file names are based. This property is required for collecting trace data for C/C++ native driver code, and therefore only applies to type 2 connectivity. You normally use this trace under the direction of IBM Software Support.

db2.jcc.t2zosTraceBufferSize Specifies the size of a trace buffer in virtual storage that is used for tracing the processing that is done by the C/C++ native driver code. This value is also the maximum amount of C/C++ native driver trace information that can be collected, and therefore only applies to type 2 connectivity. Specify a value in kilobytes. The default is 256 KB. This property is used only if the db2.jcc.t2zosTraceFile property is set. Recommendation: To avoid a performance impact, specify a value of 1024 or less. You normally set this trace property under the direction of IBM Software Support. Example 10-1 is what our sample properties file looks like.
Example 10-1 Global driver properties file db2.jcc.ssid=DBD8 db2.jcc.traceFile=/u/rc54/cel541nd541sc54ws541sc54/tracejava db2.jcc.t2zosTraceFile=/u/rc54/cel541nd541sc54ws541sc54/tracezos

Now that we have the content of the global driver properties file, we need to point WAS to the file. This is done by setting the up the db2.jcc.propertiesFile system property. In a WebShpere Application Server environment, this is done via a Custom Property on the JVM. These can be set at the WAS server level (see Figure 10-8).

Figure 10-8 JVM Custom Properties

See also 3.5.4, Defining DB2 Universal Driver - General properties on page 65, for more details on how to specify custom properties.

Chapter 10. DB2 - WebSphere performance aspects

237

Type 2 z/OS native driver code trace file


The trace file that is produced after setting the t2zosTraceFile property needs formatting to make it readable. You can use the db2jcctrace command to do this. As mentioned before, this trace is normally only used under the direction of the Support Center, and we will not discuss its format in this publication. For more information about the db2jcctrace command, see the Formatting trace data for C/C++ native driver code with the DB2 Universal JDBC Driver section in DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414.

Universal Driver trace file for Java code


The trace file that is produced after setting the traceFile property does not need additional formatting to make it readable. However, it is written in ASCII, and therefore not very readable as such on the z/OS platform. The easiest way to look at its content is to ftp it in binary to your workstation. A sample output is shown in Example 10-2. (This trace is from a type 2 connection, using an override of the trace data set at the DataSource level.)
Example 10-2 Universal Driver trace output // *****The trace starts with general driver info ***** [ibm][db2][jcc][Time:1103812830717][Thread:WebSphere t=006cc4d0][DB2ConnectionPoolDataSource@158560e7] getPooledConnection () called [ibm][db2][jcc] BEGIN TRACE_DRIVER_CONFIGURATION [ibm][db2][jcc] Driver: IBM DB2 JDBC Universal Driver Architecture 2.1.43 [ibm][db2][jcc] Compatible JRE versions: { 1.3, 1.4 } [ibm][db2][jcc] Target server licensing restrictions: { z/OS: enabled; SQLDS: enabled; iSeries: enabled; DB2 for Unix/Windows: enabled; Cloudscape: enabled } ....... // *****The trace lists the classpath it uses ***** [ibm][db2][jcc] Java class path = /WebSphereBS/V5R0M0/BS01/AppServer/properties:/WebSphereBS/V5R0M0/BS01/AppServer/lib/bootstrap.jar:/WebSphe reBS/V5R0M0/BS01/AppServer/lib/urlprotocols.jar:/WebSphereBS/V5R0M0/BS01/AppServer/lib/j2ee.jar:/WebSphereB S/V5R0M0/BS01/AppServer/lib/lmproxy.jar [ibm][db2][jcc] Java native library path = /usr/lpp/java/IBM/J1.3/bin:/usr/lpp/java/IBM/J1.3/bin/classic:/WebSphereBS/V5R0M0/BS01/AppServer/lib [ibm][db2][jcc] Path of extension directory or directories = /usr/lpp/java/IBM/J1.3/lib/ext:/WebSphereBS/V5R0M0/BS01/AppServer/java/jre/lib/ext [ibm][db2][jcc] Operating system name = z/OS [ibm][db2][jcc] Operating system architecture = 390 [ibm][db2][jcc] Operating system version = 01.04.00 [ibm][db2][jcc] File separator ("/" on UNIX) = / [ibm][db2][jcc] Path separator (":" on UNIX) = : [ibm][db2][jcc] User's account name = ASSR1 [ibm][db2][jcc] User's home directory = /tmp [ibm][db2][jcc] User's current working directory = /WebSphereBS/V5R0M0/BS01/AppServer [ibm][db2][jcc] END TRACE_DRIVER_CONFIGURATION // *****The trace lists all the propterties that are being used ***** [ibm][db2][jcc] BEGIN TRACE_CONNECTS [ibm][db2][jcc] Using properties: { cliSchema=null, readOnly=false, deferPrepares=true, currentFunctionPath=null, planName=null, loginTimeout=0, currentPackagePath=null, serverName=null, resultSetHoldability=2, portNumber=50000, activeServerListJNDIName=null, securityMechanism=3, description=null, traceFile=/u/rc54/cel541nd541sc54ws541sc54/tracejavads, dataSourceName=null, fullyMaterializeLobData=true, databaseName=DBD8, kerberosServerPrincipal=null, jdbcCollection=NULLID, clientUser=null, traceLevel=-1, user=BARTR1, currentPackageSet=SG246435, clientAccountingInformation=null, password=*******, driverType=2, currentLockTimeout=-2147483647, traceFileAppend=false, retrieveMessagesFromServerOnGetMessage=true, traceDirectory=null, pkList=null, keepDynamic=0,

238

DB2 for z/OS and WebSphere: The Perfect Couple

currentSQLID=null, cursorSensitivity=0, clientApplicationInformation=null, currentSchema=null, clientWorkstation=null } [ibm][db2][jcc] END TRACE_CONNECTS [ibm][db2][jcc][Time:1103812831057][Thread:WebSphere t=006cc4d0][Connection@371ee0e5] T2zosConnection () called // ***** Trace records specific to z/OS type 2 connectivit are marked [t2zos] ***** [ibm][db2][jcc][t2zos] [Thread:WebSphere t=006cc4d0][com.ibm.db2.jcc.t2zos.T2zosReusableConnection@371ee0e5] flowConnect () tracepoint 1 [ibm][db2][jcc][t2zos] (database name) [ibm][db2][jcc][t2zos] (ASCII) (EBCDIC) [ibm][db2][jcc][t2zos] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [ibm][db2][jcc][t2zos] 0000 C4C2C4F800 ..... DBD8. [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] (user) [ibm][db2][jcc][t2zos] (ASCII) (EBCDIC) [ibm][db2][jcc][t2zos] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [ibm][db2][jcc][t2zos] 0000 C2C1D9E3D9F100 ....... BARTR1. ... [ibm][db2][jcc][Connection@371ee0e5] BEGIN TRACE_CONNECTS [ibm][db2][jcc][Connection@371ee0e5] Successfully connected to server jdbc:db2:DBD8 [ibm][db2][jcc][Connection@371ee0e5] User: BARTR1 [ibm][db2][jcc][Connection@371ee0e5] Database product name: DB2 [ibm][db2][jcc][Connection@371ee0e5] Database product version: DSN08015 [ibm][db2][jcc][Connection@371ee0e5] Driver name: IBM DB2 JDBC Universal Driver Architecture [ibm][db2][jcc][Connection@371ee0e5] Driver version: 2.1.43 [ibm][db2][jcc][Connection@371ee0e5] DB2 Application Correlator: TBD for T2zos [ibm][db2][jcc][Connection@371ee0e5] END TRACE_CONNECTS [ibm][db2][jcc][Connection@371ee0e5] BEGIN TRACE_CONNECTS [ibm][db2][jcc][Connection@371ee0e5] Successfully connected to server jdbc:db2:DBD8 [ibm][db2][jcc][Connection@371ee0e5] User: BARTR1 [ibm][db2][jcc][Connection@371ee0e5] Database product name: DB2 [ibm][db2][jcc][Connection@371ee0e5] Database product version: DSN08015 [ibm][db2][jcc][Connection@371ee0e5] Driver name: IBM DB2 JDBC Universal Driver Architecture [ibm][db2][jcc][Connection@371ee0e5] Driver version: 2.1.43 [ibm][db2][jcc][Connection@371ee0e5] DB2 Application Correlator: TBD for T2zos [ibm][db2][jcc][Connection@371ee0e5] END TRACE_CONNECTS ... [ibm][db2][jcc][Time:1103812831807][Thread:WebSphere t=006cc4d0][ConnectedProfile@1f42e0fb] getStatement (SELECT EMPNO , FIRSTNME , MIDINIT , LASTNAME , HIREDATE , CASE SEX WHEN 'M' THEN 1 ELSE 0 END , SALARY FROM EMP ) called [ibm][db2][jcc][Time:1103812831847][Thread:WebSphere t=006cc4d0][RTStatement@45120fb] <constructor> () called ... [ibm][db2][jcc][Time:1103812832255][Thread:WebSphere t=006cc4d0][RTStatement@45120fb] executeRTQuery () called [ibm][db2][jcc][Time:1103812832255][Thread:WebSphere t=006cc4d0][PreparedStatement@57fca0f8] executeQuery () called [ibm][db2][jcc][t2zos] [Thread:WebSphere t=006cc4d0][com.ibm.db2.jcc.t2zos.T2zosPreparedStatement@10e820f8] getNativeStatement () tracepoint 1 [ibm][db2][jcc][t2zos] (pCONN) 355087216 // *****The trace indicates the package name being used - in this case a static SQLJ package ***** [ibm][db2][jcc][t2zos] (package name) [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] 0 1 2 3 4 5 6 7 8 9 A B C D E F [ibm][db2][jcc][t2zos] 0000 C5D4D7D3D6E8F300 [ibm][db2][jcc][t2zos]

(ASCII) (EBCDIC) 0123456789ABCDEF 0123456789ABCDEF ........ EMPLOY3.

Chapter 10. DB2 - WebSphere performance aspects

239

[ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] [ibm][db2][jcc][t2zos] ....

(section number) 5 (consistency token) 0 1 2 3 4 5 6 7 8 9 A B C D E F 4D41447044434C71 (ASCII) (EBCDIC) 0123456789ABCDEF 0123456789ABCDEF MADpDCLq (.....<.

0000

(statement class) 3 (static statement type) 231

DataSource level tracing


In most cases, the most convenient way to activate Universal Driver Java code tracing is to set properties at the DataSource level. This way you have more control over where tracing is activated, as you specify these properties at the individual datasource level. (Note that you cannot turn on native C/C++ driver code tracing at the datasource level.) These settings apply to both type 2 and type 4 connectivity. In a WebSphere Application Server, tracing can be set as Custom Properties at the DataSource level. The following properties are available: traceDirectory Specifies a directory into which trace information is written. When traceDirectory is specified, trace information for multiple connections on the same DataSource is written to multiple files. (traceDirectory is mutually exclusive with the traceFile property, which directs all trace information to a single file.) When traceDirectory is specified, a connection is traced to a file named traceFile_origin_n. n is the nth connection for a DataSource. origin indicates the origin of the log writer that is in use. Possible values of origin are: cpds driver ds global sds xads traceFile The log writer for a DB2ConnectionPoolDataSource object The log writer for a DB2Driver object The log writer for a DB2DataSource object The log writer for a DB2TraceManager object The log writer for a DB2SimpleDataSource object The log writer for a DB2XADataSource object

Specifies the name of a file into which the Universal Driver writes trace information. (The traceFile property is an alternative to the logWriter property for directing the output trace stream to a file.) For Universal Driver type 2 connectivity, the db2.jcc.override.traceFile global property value overrides the traceFile property value. Specifies whether to append to or overwrite the file that is specified by the traceFile property. The default is false, which means that the file that is specified by the traceFile property is overwritten. Specifies what to trace. The trace levels that you can specify are described in Trace levels on page 236.

traceFileAppend

traceLevel

These properties can also be set for a Connection object, but our interest here is DataSources, as they are the preferred way to set up a connection to a data source in WebSphere. To set these properties on the WebSphere datasource, you use the Administrative Console. Navigate to Resources JDBC Providers provider-name Data Sources datasource-name Custom Properties (Figure 10-9 on page 241).

240

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 10-9 Custom Properties trace options

This example only sets the traceFile and traceLevel properties, as these are supported by the Admin console panels. If you want to use traceDirectory and traceAppend, you would have to create these as additional custom properties (using the New button). Figure 10-3 shows (edited) trace output from a type 4 XA connection. (As with the driver-wide trace file, this one is also written in ASCII, and you have to download it in binary to read it.)
Example 10-3 Data source level trace output // *****Again we start with a driver configuration listing versions and options used ***** [ibm][db2][jcc] BEGIN TRACE_DRIVER_CONFIGURATION [ibm][db2][jcc] Driver: IBM DB2 JDBC Universal Driver Architecture 1.7.9 [ibm][db2][jcc] Compatible JRE versions: { 1.3, 1.4 } [ibm][db2][jcc] Target server licensing restrictions: { z/OS: enabled; SQLDS: enabled; iSeries: enabled; DB2 for Unix/Windows: enabled; Cloudscape: enabled } .... [ibm][db2][jcc] Java class path = /WebSphereBS/V5R0M0/BS02/AppServer/properties:/WebSphereBS/V5R0M0/BS02/AppServer/lib/bootstrap.jar:/WebSphe reBS/V5R0M0/BS02/AppServer/lib/urlprotocols.jar:/WebSphereBS/V5R0M0/BS02/AppServer/lib/j2ee.jar:/WebSphereB S/V5R0M0/BS02/AppServer/lib/lmproxy.jar [ibm][db2][jcc] Java native library path = /usr/lpp/java/IBM/J1.3/bin:/usr/lpp/java/IBM/J1.3/bin/classic:/WebSphereBS/V5R0M0/BS02/AppServer/lib [ibm][db2][jcc] Path of extension directory or directories = /usr/lpp/java/IBM/J1.3/lib/ext:/WebSphereBS/V5R0M0/BS02/AppServer/java/jre/lib/ext [ibm][db2][jcc] Operating system name = z/OS [ibm][db2][jcc] Operating system architecture = 390

Chapter 10. DB2 - WebSphere performance aspects

241

[ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc] [ibm][db2][jcc]

Operating system version = 01.05.00 File separator ("/" on UNIX) = / Path separator (":" on UNIX) = : User's account name = ASSR1 User's home directory = /tmp User's current working directory = /WebSphereBS/V5R0M0/BS02/AppServer END TRACE_DRIVER_CONFIGURATION BEGIN TRACE_CONNECTS

// *****The trace indicates connection start, listing all properties used ***** [ibm][db2][jcc] Attempting connection to wtsc54.itso.ibm.com:38070/DBD8 [ibm][db2][jcc] Using properties: { password=********, dataSourceName=null, traceDirectory=null, portNumber=38070, fullyMaterializeLobData=true, currentSQLID=null, securityMechanism=3, clientAccountingInformation=null, cliSchema=null, resultSetHoldability=2, serverName=wtsc54.itso.ibm.com, currentPackageSet=SG246435, loginTimeout=0, planName=null, traceFile=/u/rc55/cel551nd551sc55/traceT4XA, currentFunctionPath=null, kerberosServerPrincipal=null, retrieveMessagesFromServerOnGetMessage=true, cursorSensitivity=0, currentPackagePath=null, currentSchema=null, clientUser=null, keepDynamic=0, driverType=4, clientApplicationInformation=null, description=null, readOnly=false, clientWorkstation=null, pkList=null, deferPrepares=true, jdbcCollection=NULLID, databaseName=DBD8, traceLevel=-1, traceFileAppend=false, user=BART } [ibm][db2][jcc] END TRACE_CONNECTS // *****The trace indicates type 4 connectivity specific entries by [t4] ***** // *****Also note the type 4 connectivity also shows the DRDA flows (like EXCSAT) and buffer content ***** [ibm][db2][jcc] [T4][time:1103815956665][thread:WebSphere t=006cad90][tracepoint:1][Request.flush] [ibm][db2][jcc][t4] SEND BUFFER: EXCSAT (ASCII) (EBCDIC) [ibm][db2][jcc][t4] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [ibm][db2][jcc][t4] 0000 0068D00100010062 1041001E115E8482 .h.....b.A...^.. ..}..........;db [ibm][db2][jcc][t4] 0010 F2918383E68582E2 978885998540A37E .............@.~ 2jccWebSphere t= [ibm][db2][jcc][t4] 0020 F0F0F6838184F9F0 000A116DA6A3A283 ...........m.... 006cad90..._wtsc [ibm][db2][jcc][t4] 0030 F5F5000E115AC4C2 F2D1C3C340F14BF0 .....Z......@.K. 55...!DB2JCC 1.0 [ibm][db2][jcc][t4] 0040 001C140414030007 24070007240F0007 ........$...$... ................ [ibm][db2][jcc][t4] 0050 1440000614740005 1C010007000C1147 .@...t.........G . .............. [ibm][db2][jcc][t4] 0060 D8C4C2F261D1E5D4 ....a... QDB2/JVM [ibm][db2][jcc][t4] [ibm][db2][jcc] [t4][time:1103815956668][thread:WebSphere t=006cad90][tracepoint:2][Reply.fill] ... [ibm][db2][jcc][Connection@6f5b2602] BEGIN TRACE_CONNECTS [ibm][db2][jcc][Connection@6f5b2602] Successfully connected to server jdbc:db2://wtsc54.itso.ibm.com:38070/DBD8 [ibm][db2][jcc][Connection@6f5b2602] User: BART [ibm][db2][jcc][Connection@6f5b2602] Database product name: DB2 [ibm][db2][jcc][Connection@6f5b2602] Database product version: DSN08015 [ibm][db2][jcc][Connection@6f5b2602] Driver name: IBM DB2 JDBC Universal Driver Architecture [ibm][db2][jcc][Connection@6f5b2602] Driver version: 1.7.9 [ibm][db2][jcc][Connection@6f5b2602] DB2 Application Correlator: G90C041C.G498.0101008ED8A4 [ibm][db2][jcc][Connection@6f5b2602] END TRACE_CONNECTS [ibm][db2][jcc][t4] DRDA manager levels: { SQLAM=7, AGENT=7, CMNTCPIP=5, RDB=7, SECMGR=6 } [ibm][db2][jcc][Time:1103815956735][Thread:WebSphere t=006cad90][Connection@6f5b2602] setDB2ClientUser (BART) called [ibm][db2][jcc][Time:1103815956736][Thread:WebSphere t=006cad90][Connection@6f5b2602] setDB2ClientWorkstation (wtsc55) called [ibm][db2][jcc][Time:1103815956736][Thread:WebSphere t=006cad90][Connection@6f5b2602] setDB2ClientApplicationInformation (db2jccWebSphere t=006cad90) called [ibm][db2][jcc][Time:1103815956736][Thread:WebSphere t=006cad90][DB2XAConnection@d1da60d] getConnection () called ...

242

DB2 for z/OS and WebSphere: The Perfect Couple

[ibm][db2][jcc][Time:1103815957228][Thread:WebSphere t=006cad90][Customization@21a5a601] getProfile () returned com.ibm.db2.jcc.sqlj.c@772c2601 [ibm][db2][jcc][Time:1103815957228][Thread:WebSphere t=006cad90][ConnectedProfile@772c2601] getStatement (SELECT EMPNO , FIRSTNME , MIDINIT , LASTNAME , HIREDATE , CASE SEX WHEN 'M' THEN 1 ELSE 0 END , SALARY FROM EMP ) called [ibm][db2][jcc][Time:1103815957295][Thread:WebSphere t=006cad90][RTStatement@5eca6601] <constructor> () called [ibm][db2][jcc][Time:1103815957369][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] getMaxFieldSize () called [ibm][db2][jcc][Time:1103815957369][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] setMaxFieldSize (0) called [ibm][db2][jcc][Time:1103815957369][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] getFetchSize () returned 0 [ibm][db2][jcc][Time:1103815957370][Thread:WebSphere t=006cad90][ConnectedProfile@772c2601] getStatement () returned com.ibm.db2.jcc.sqlj.g@5eca6601 [ibm][db2][jcc][Time:1103815957370][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] setMaxRows (0) called [ibm][db2][jcc][Time:1103815957370][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] setMaxFieldSize (0) called [ibm][db2][jcc][Time:1103815957370][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] setQueryTimeout (0) called [ibm][db2][jcc][Time:1103815957371][Thread:WebSphere t=006cad90][RTStatement@5eca6601] executeRTQuery () called [ibm][db2][jcc][Time:1103815957371][Thread:WebSphere t=006cad90][PreparedStatement@3ef42601] executeQuery () called [ibm][db2][jcc] [t4][time:1103815957390][thread:WebSphere t=006cad90][tracepoint:1][Request.flush] [ibm][db2][jcc][t4] SEND BUFFER: EXCSQLSET (ASCII) (EBCDIC) [ibm][db2][jcc][t4] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [ibm][db2][jcc][t4] 0000 004ED05100010048 201400442113C4C2 .N.Q...H ..D!... .+}...........DB [ibm][db2][jcc][t4] 0010 C4F8404040404040 4040404040404040 ..@@@@@@@@@@@@@@ D8 [ibm][db2][jcc][t4] 0020 E2C7F2F4F6F4F3F5 4040404040404040 ........@@@@@@@@ SG246435 [ibm][db2][jcc][t4] 0030 4040E2E8E2D3D5F2 F0F0404040404040 @@........@@@@@@ SYSLN200 [ibm][db2][jcc][t4] 0040 404040405359534C 564C303101810027 @@@@SYSLVL01...' ...<.<...a.. [ibm][db2][jcc][t4] 0050 D053000100212414 0000000017534554 .S...!$......SET }............... [ibm][db2][jcc][t4] 0060 20434C49454E5420 5553455249442742 CLIENT USERID'B ..<..+.......... [ibm][db2][jcc][t4] 0070 41525427FF002DD0 5300010027241400 ART'..-.S...'$.. .......}........ [ibm][db2][jcc][t4] 0080 0000001D53455420 434C49454E542057 ....SET CLIENT W .........<..+... [ibm][db2][jcc][t4] 0090 524B53544E4E414D 4527777473633535 RKSTNNAME'wtsc55 ....++.(........ [ibm][db2][jcc][t4] 00A0 27FF003FD0530001 0039241400000000 '..?.S...9$..... ....}........... [ibm][db2][jcc][t4] 00B0 2F53455420434C49 454E54204150504C /SET CLIENT APPL ......<..+...&&< [ibm][db2][jcc][t4] 00C0 4E414D4527646232 6A63635765625370 NAME'db2jccWebSp +.(.....|....... [ibm][db2][jcc][t4] 00D0 6865726520743D30 3036636164393027 here t=006cad90' .........../.... [ibm][db2][jcc][t4] 00E0 FF005FD043000100 592414000000004F .._.C...Y$.....O ...}...........| [ibm][db2][jcc][t4] 00F0 53455420434C4945 4E5420414343544E SET CLIENT ACCTN .....<..+......+ [ibm][db2][jcc][t4] 0100 47274A4343303130 37304A564D202020 G'JCC01070JVM ............(... [ibm][db2][jcc][t4] 0110 2020202020202020 202020206462326A db2j ...............| [ibm][db2][jcc][t4] 0120 6363576562537068 65726520743D3030 ccWebSphere t=00 ................ [ibm][db2][jcc][t4] 0130 4241525420202020 272C5827303027FF BART ',X'00'. ................ [ibm][db2][jcc][t4] 0140 005BD00100020055 200C00442113C4C2 .[.....U ..D!... .$}...........DB [ibm][db2][jcc][t4] 0150 C4F8404040404040 4040404040404040 ..@@@@@@@@@@@@@@ D8 [ibm][db2][jcc][t4] 0160 E2C7F2F4F6F4F3F5 4040404040404040 ........@@@@@@@@ SG246435 [ibm][db2][jcc][t4] 0170 4040C5D4D7D3D6E8 F340404040404040 @@.......@@@@@@@ EMPLOY3 [ibm][db2][jcc][t4] 0180 404040404D414470 44434C7100050008 @@@@MADpDCLq.... (.....<..... [ibm][db2][jcc][t4] 0190 211400007FFF0005 215D01 !.......!]. ...."....). [ibm][db2][jcc][t4] [ibm][db2][jcc] [t4][time:1103815957430][thread:WebSphere t=006cad90][tracepoint:2][Reply.fill] [ibm][db2][jcc][t4] RECEIVE BUFFER: SQLCARD (ASCII) (EBCDIC) [ibm][db2][jcc][t4] 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0123456789ABCDEF [ibm][db2][jcc][t4] 0000 000BD04300010005 2408FF002FD05200 ...C....$.../.R. ..}..........}.. ...

Chapter 10. DB2 - WebSphere performance aspects

243

ibm][db2][jcc][t4] 00C0 08241B0000079BFF [ibm][db2][jcc][t4] 00D0 09C3C8D9C9E2E3C9 [ibm][db2][jcc][t4] 00E0 E200F1F9F6F560F0 [ibm][db2][jcc][t4] 00F0 00005275000CFF00 [ibm][db2][jcc][t4] 0100 E5C9D5C3C5D5E9D6 [ibm][db2][jcc][t4] 0110 C5E2C900F1F9F5F8 [ibm][db2][jcc][t4] 0120 000100004650000C ...

00F0F0F0F0F1F000 D5C5C90004C8C1C1 F160F0F100000000 F0F0F0F1F1F00008 C70008D3E4C3C3C8 60F0F560F1F60000 FF00F0F0F0F1F2F0

.$.............. ................ ......`..`...... ..Ru............ ................ ........`..`.... ....FP..........

.........000010. .CHRISTINEI..HAA S.1965-01-01.... ........000110.. VINCENZOG..LUCCH ESI.1958-05-16.. .....&....000120

Note: If you are tracing a type 4 connection, as in the example above, you can also see the DRDA flows, including the content of the send and receive buffers (provided TRACE_DRDA_FLOWS tracing is active).

10.6.2 DB2SystemMonitor class


To help you isolate performance problems with your applications, the DB2 Universal Driver for SQLJ and JDBC provides a proprietary API (DB2SystemMonitor class) to enable applications to do monitoring. The driver collects the following timing information: Server time (the time spent in DB2 itself) Network I/O time (the time used to flow the DRDA protocol stream across the network) Core driver time (the time spent in the driver; this includes network I/O time and server time) Application time (the time between the start() and stop() calls) For more information on how to switch on the JCC DB2SystemMonitor class, see 12.3.6 Java API for application monitoring of DB2 for z/OS and OS/390: Ready for Java, SG24-6435. When running in a WAS V5 environment, the DB2SystemMonitor class is not accessible by your applications. This will, however, change with the next WAS version. WebSphere Application Server will provide a com.ibm.websphere.rsadapter.WSSystemMonitor class to do so. An example of what to expect is shown in Example 10-4.
Example 10-4 WSSystemMonitor example WSConnection wcon = (WSConnection)ds.getConnection(); WSSystemMonitor smon = wcon.getSystemMonitor(); System.out.println("############ gettenig the system monitor is:" + smon); if (smon != null) { smon.enable(true); smon.start(WSSystemMonitor.RESET_TIMES); // ...... SQL statements .... smon.stop(); System.out.println("Server time: " + monitor.getServerTimeMicros()); System.out.println("Network I/O time: " + monitor.getNetworkIOTimeMicros()); System.out.println("Core driver time: " + monitor.getCoreDriverTimeMicros()); System.out.println("Application time (ms): " + monitor.getApplicationTimeMillis()); }else System.out.println("############ System monitor is not supported on this backend");

Note that we also use the WSConnection class (not DB2Connection), as in Example 6-2 on page 137.

244

DB2 for z/OS and WebSphere: The Perfect Couple

11

Chapter 11.

Sample application
In this chapter we describe a sample application using Enterprise JavaBeans (mostly entity Beans) of different types, to show how DB2 data can be accessed from within Web applications using data source definitions based on the new IBM DB2 Universal Driver for SQLJ and JDBC.

Copyright IBM Corp. 2005. All rights reserved.

245

11.1 Introduction
Our sample Web application is based on the contents of the DB2 IVP tables provided with DB2 for z/OS Version 8. Our scenario uses a Model View Controller (MVC2) approach, as shown in Figure 11-1. Note: In the MVC1 model, the controller was also provided as a Java ServerPage. In the MVC2 model, it is Servlet.

View
1.

Controller
Java Servlet Navigator
4. 3. 2.

Model
Backend Transaction: EJB CICS IMS DB2 JMS(MQI) Java

HTTP(S)
5.

Java Server Page


Database

WebSphere Application Server


Figure 11-1 MVC design

In the MVC model there are three clearly distinct groups of components: Controller: Accepts queries from the browser, dispatches the required actions to the models, and interacts for presentation with the views. It acts as the navigator in the design. The controller always contains a Servlet. Views: Composed of JavaServer Pages and special Servlets (in case some MIME types are not supported by JSP), they are responsible for rendering the output to the user. Models: These are the business components. The real work is done here. A model can be a group of Enterprise JavaBeans, both session and entity, a connector to a transaction in a transaction manager (CICS,IMS), or it can be a simple JavaBean with some logic. Although the main interest of this book lays in DB2 and access to DB2 from WAS, we should not forget that DB2 is a database manager, and that it comes to life on behalf of transactions. The transactions trigger the accesses to DB2. To access the DB2 data, we use several kinds of entity Beans (EJBs) in our sample application. The transaction in a WAS environment often originates from a browser, and the results have to be presented back to this browser. The access to DB2 tables is located inside the models. We use all combinations of entity Beans to access those DB2 tables in our sample application. We will start out building the model part of our design. Later in a Web project we will add the controller and the view. The model in our case is composed of one session Bean, which receives the requests from dispatched actions in the controller, and collects the required data from entity Beans, which then is returned to the controller component and presented by the views.

246

DB2 for z/OS and WebSphere: The Perfect Couple

In Figure 11-2 we recognize the three MVC parts. The requests come from the browser, and are accepted by the controller.

b ro w s e r

M odel
E n t it y B e a n s

V ie w

C o n t r o lle r
a c t io n s

IT S O A c c e s s S e s s io n E J B
g e tE m p lo y e e () g e tIm a g e () g e tD e p a rtm e n t() g e tD e p E m p lo y e e L is t()

J S P 's

S e r v le t

P h o t o E m p lo y e e CMP P h o t o E m p lo y e e BMP P h o t o E m p lo y e e C M P /S Q L J P h o t o E m p lo y e e B M P /S Q L J E m p lo y e e CMP E m p lo y e e C M P /S Q L J E m p lo y e e B M P /S Q L J D e p a rtm e n t CMP

T4
A c tio n C o n tro l

T2
DB2

E J B 's

Figure 11-2 MVC design with session Bean as entry to model

The DB2 sample tables provided with DB2 for z/OS V8 show a lot of complex aspects of DB2, especially in the area of referential integrity. Since this publication focuses on the WebSphere Application Server (WAS) aspects of using DB2, and we like to cover the elements offered by the EJB 2.0 specification, we simplified the set of sample tables. We only use the Employee (EMP), Department (DEPT) and the Emp_Photo_Resume (EMP_PHOTO_RESUME) tables, and the relationships that have been defined between these tables through foreign keys (FK). The Emp_Photo_Resume table is a stand-alone table and contains BLOB data (a picture of the employee) and CLOB data (the employees resume) that we use to demonstrate the usage of LOB columns in Java-DB2 programs. We will now concentrate on the model. The model has a front-end session Bean with the four business methods that can be triggered by a browser request: employeeEJB.do -> getEmployee(): To retrieve the details of an employee getImage(): To retrieve the picture of an employee departmentEJB.do -> getDepartment(): To retrieve the details of a department departmentListEJB.do -> getDepartmentList(): To list the employees belonging to a department All demands from the controller actions are passed through this session Bean, which with parameters passed in a container (actually a java.util.HashMap), it makes a selection of entity Beans to collect the requested information from, and passes it back to the controller via a data transfer Bean. The session Bean is responsible for the lookup of the entity Beans and for collecting some of the contents of the data transfer Beans. In our sample scenario (Figure 11-2), we use several types of entity Beans. We use container-managed persistence (CMP) Beans using JDBC or SQLJ, which have been generated by Websphere Application Studio Developer (WSAD). We also use Bean-managed persistence (BMP) with JDBC and SQLJ for some tables.

Chapter 11. Sample application

247

The development of the design is be done under WSAD V5.1 on a workstation (Windows-based in our case). We use and show the following aspects of the application: Connecting from WSAD to DB2 and import of table schemas Mapping of the tables to container-managed persistence Beans (CMP) Definition and exploitation of the container-managed relationships (CMR) Using the EJBQL language to add additional finders Generation of the deployment code Integration of the CMP Beans in a Web project based on Struts Integration of the BMP Beans with JDBC code Integration of the CMP Beans with SQLJ code Integration of the BMP Beans with SQLJ code

11.1.1 Sample table description


The sample application is based on the three tables mentioned before. The schema name we use is ITSOUSER.

EMP and DEPT tables


These tables contain textual information about employees and department. As shown in Figure 11-3, each table has a primary key: EMP(empno) DEPT(deptno)
D a ta b a s e IT S O D B
Ta b le S p a c e T S E M P
IN D E X X E M P 1
(E M P N O )

D a ta b a s e IT S O D B L
Ta b le S p a c e T S L O B 1
BASE TABLE E M P _ P H O TO _ R E S U M E
P rim ary K e y E M P N O

TABLE EMP
P rim a ry K e y E M P N O

IN D E X X E M P 2
(W O R K D E P T )

IN D E X X E M P _ P H O TO _ R E S U M E
F o re ign K e y R D E P T o n co lu m n W O R K D E P T ON DELETE SET N ULL F ore ig n K e y R E M P o n co lu m n M G R N O O N D E LE T E S E T N U L L

(E M P N O )

L O B Ta b le S p a c e T S L O B 2
AUX TABLE A U X _ P S E G _ P H O TO

Ta b le S p a c e T S D E P T
IN D E X X D E P T 1
(D E P T N O )

TABLE DEPT
P rim a ry K e y D E P T N O

L O B Ta b le S p a c e T S L O B 3
AUX TABLE A U X _B M P _ P H O TO

IN D E X X D E P T 2
(M G R N O )

IN D E X X D E P T 3
(A D M R D E P T )
F o reig n K e y R S E L F D o n c olu m n A R M R D E P T ON DELETE CASCAD E

L O B Ta b le S p a c e T S L O B 4
AU X TABLE AU X_EM P _R ES U M E

A ll o b je cts c re a te d b y IT S O U S E R (S C H E M A is IT S O U S E R )

Figure 11-3 Application sample tables

We also have three relationships between the tables, defined by the following foreign keys: EMP(workdept) -> DEPT(deptno) = RDEPT DEPT(mgnro) -> EMP(empno) = REMP DEPT(admrdept) -> DEPT(deptno) = RSELFD

248

DB2 for z/OS and WebSphere: The Perfect Couple

EMP_PHOTO_RESUME
This table contains large object (LOB) columns. Physically, the logical table is materialized by a base table and one auxiliary table for each (LOB) column, which can be a binary one (BLOB) or a character one (CLOB). There are no relations with other tables, but a primary key exists on the EMPNO column. The EMP_PHOTO_RESUME table has one CLOB and two BLOB (picture) columns.

11.1.2 Importing the tables into WSAD


We assume that you have WebSphere Studio Application Developer installed. During the project, we used Version 5.1. We also assume that you are familiar with the projects and perspectives concepts used by WSAD. For more information on the use of WSAD, see WebSphere Studio Application Developer Version 5 Programming Guide, SG24-6957.

Connecting to DB2
Before we can do any development work with the DB2 tables in WSAD, it is required to connect to the DB2 system where they are located. To generate container-managed persistence (CMP) entity Beans, we have to import the schema metadata information from DB2 into the WSAD workbench. This happens in a data perspective of WSAD. First we have to define a connection to the DB2 system. When connecting to a DB2 V7 or V8 system using the IBM DB2 Universal Driver for SQLJ and JDBC, we have a choice in the connection type (T2 or T4). Since our data model is identical on DBD7 and DBD8, it does not really matter which system we use. All preparation work shown in this publication has been done against a DB2 V8 system, using type 4 connectivity. Note: This connection is only used for importing table schemas, not when running the actual application under a WebSphere Application Server.

Which table qualifier to use


During the CMP preparation, we like to use a bottom-up approach. This means that we start from an existing set of tables to generate the CMP Beans from. Those tables have a qualifier, in our case ITSOUSER. When you generate CMP Beans using the bottom-up approach, based on these tables, they will already be tied to these specific tables. During the development of a Bean, it is better to work unqualified. Therefore, instead of generating the CMPs from qualified tables, we generate them from unqualified tables. To do so, you can create the tables with the NULLID qualifier (for example, NULLID.EMP). As a result, the JDBC or SQLJ statements that are generated by the WSAD wizard will be without a qualifier in the table name. You can obtain NULLID qualified tables in different ways: For all the tables qualified with ITSOUSER, make shadow tables that use NULLID as a table qualifier, and import from those tables. Import the ITSOUSER tables, and change the schema under the back-end in the EJB project to NULLID. Import the ITSOUSER tables, generate the CMP bottom-up, and use the existing CMP artifacts to generate a NULLID schema with a top-down approach. The second method is probably the most useful.

Chapter 11. Sample application

249

Connection definition
In the data perspective, inside the DB Servers pane, located in the bottom-left part of the WSAD window, right-click New Connection (Figure 11-4).

Figure 11-4 New Connection

A New Database Connection window pops up, as shown in Figure 11-5. Fill in the fields, as indicated in Figure 11-5, and select to use a connection using T4 connectivity. Note: At the time of writing, the selection option Database vendor type in WSAD did not include DB2 Universal Database for OS/390, V8, but functionally it makes no difference.

Figure 11-5 Connection definition

Table 11-1 on page 251 explains the important fields of Figure 11-5.

250

DB2 for z/OS and WebSphere: The Perfect Couple

Table 11-1 Connection properties Field name Connection name Database Value DBD8T4 DBD8 Comment Any name that describes the connection. Location name of the DB2 for z/OS system that harbors your tables. Will be corrected in a future WSAD release. Select the JCC driver. IP host name. Port number DBD8 is listening on. This is automatically selected (and cannot be updated), and is related to the selection made in the JDBC driver field. Mandatory JAR files, containing the driver classes. Automatically filled in based on the information provided in JDBC driver, host, and port number. Remember that type 4 connectivity requires the following information in the connection URL: - DDF TCP/IP port on DBD8 - Location name of DBD8

Database vendor type JDBC driver Host Port number JDBC driver class

DB2 Universal Database for OS/390, V7 IBM DB2 UNIVERSAL DRIVER wtsc54.itso.ibm.com 38070 com.ibm.db2.jcc.DB2Driver

Class location

..\SQLLIB\java\db2jcc_license_cu.jar; ..\SQLLIB\java\db2jcc.jar jdbc:db2://wtsc54.itso.ibm.com:38070/DBD 8

Connection URL

Click Finish. A secondary window Confirm Filters, shown in Figure 11-6, pops up. It provides you with the possibility to define filters, so that only the metadata for a selection of the tables in the DB2 subsystem are imported. The filter usage is quite important, as a DB2 for z/OS can have many tables. An import of the metadata of all tables would take too long and not be useful.

Figure 11-6 Confirm Filters selection

At this time click Update Filter. The next widow that appears is shown in Figure 11-7 on page 252. There we can specify filter criteria.

Chapter 11. Sample application

251

Figure 11-7 Filter setting to NULLID

We set the filter to enabled, and specify SCHEMA LIKE NULLID%. Click OK on the current pop-up and then Continue on the new Confirm Filters pop-up. For our sample scenario, three tables are imported: NULLID.EMP NULLID.DEPT NULLID.EMP_PHOTO_RESUME (1) (2) (3)

Table (1) and (2) are, as already mentioned, interrelated by referential integrity constraints, and as a result, will have interrelated entity Beans. Table (3) is a stand-alone table in the WSAD project. If the result of this import is not as expected, errors, or only partial data, review first the DBV8 installation and preparation. This setup is described in 1.9, Using the DB2 Universal Driver for SQLJ and JDBC on page 26, and in UDB for z/OS Installation Guide, GC18-7418. After the import completes, the new look of the DB Servers pane in WSAD should look like Figure 11-8 on page 253. Still being in the Data perspective, in the same DB Servers pane, notice the new connection named DBD8T4, which has been used for the import, and under the name of the connection (DBD8T4), the metadata for the three imported tables. In our case, we had a set of tables with a NULLID qualifier.

252

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-8 New look of the DB Servers pane

11.2 MVC model with entity Beans and a session Bean


In the scenario we build several types of entity Beans, even for the same table. Two types of entity Beans are availablecontainer-managed Persistence (CMP) and Bean-managed persistence (BMP). Both can work with JDBC and SQLJ. For the model component, we have the following types: CMP/JDBC Beans for the three tables (EMP, DEPT, EMP_PHOTO_RESUME) BMP/JDBC Bean for EMP_PHOTO_RESUME CMP/SQLJ for (EMP, DEPT, EMP_PHOTO_RESUME) BMP/SQLJ for EMP

11.2.1 Creating entity CMP Beans using JDBC from the imported tables
When creating Enterprise JavaBeans using WSAD, they have to reside in an EJB project. In this section we generate container-managed Persistence (CMP) Beans that use JDBC for our three tables that we imported in the previous section.

Creation of an EJB project


Based on the imported tables, we create an EJB project ItsoEJB1 in WSAD, in which we will generate the container-managed persistence entity Beans (CMP). Left-click New in left top corner of your WSAD work space (Figure 11-9).

Figure 11-9 New button

A pop-up (Figure 11-10 on page 254) shows up with the project/type selections.

Chapter 11. Sample application

253

Figure 11-10 Project selections

We select EJB in the left column, and EJB project in the right column. Click Next. A window like Figure 11-11 shows up next.

Figure 11-11 EJB level specification

Indicate an EJB2.0 project and click Next. EJB 2.0 types are new with WAS V5 and J2EE 1.3. Enter the name ItsoEJB1 as the EJB project name (Figure 11-12), and do not forget to also enter a name for the Enterprise Application (EA) this project is part of. We choose the name Itso1EAR, as all ingredients of J2EE projects finally are packaged in an Enterprise Archive (EAR) and deployed via this file in the WebSphere containers. It is not required to create a client EJB project in our scenario.

Figure 11-12 Project name and Enterprise Application

Finally, click Finish, and the two projects (ItsoEJB1 and Itso1EAR) are created.

254

DB2 for z/OS and WebSphere: The Perfect Couple

Importing the tables into a folder of the EJB project


Look for a DB Servers view in the Data or J2EE perspective. Find the connection (DBD8T4) corresponding with the imported tables in WSAD, and put focus on the three tables that have been imported, as shown in Figure 11-13

Figure 11-13 Import to folder in EJB project

Right-click Import to Folder. In the new window (Figure 11-14) that shows up, we have to indicate the project/folder in which the tables have to be imported.

Figure 11-14 Select of the import folder

Click the Browse button. This allows us (in a new pop-up) to navigate to the project/folder EjbModule under the ItsoEJB1 project. After clicking OK the Folder selection line is filled in, and we click Finish. The system will ask a few times for the creation authorization of new subfolders. Those should be confirmed, and finally after a while the ItsoEJB1 project looks like Figure 11-15 on page 256 (in the Data Definition window of the Data perspective).

Chapter 11. Sample application

255

Figure 11-15 EJB project after import

In the project tree we notice the additional sub folders that have been created META-INF/backends/DB2UDBOS390_v7_1. Note: The usage of the DB2UDBOS390_v7_1 directory may be confusing. We indeed work with a DB2 V8 system, but the DB2 V8 labeling was not yet supported in WSAD V5.1 at the time of writing. In the J2EE perspective, in the top left Project Navigator view, under the sub folder META-INF/backends/DB2UDBOS390_v7_1, we find metafiles *.tblxmi for the three imported tables. These files will be the sources for the Entity EJBs mapping. The backends notion indicates already that we can have tables from several backends in the same EJB project. Before we can do the mapping, we will have a look at those files and verify that all required ingredients are present. One important requirement is that each table, which will be mapped to an entity Bean, must have a primary key. We can open the *.tblxmi files with the table editor. We start with the NULLID.DEPT table. Double-clicking the file NULLID_DEPT.tblxmi opens up a first pane (see Figure 11-16 on page 257), which is the overview pane. At the bottom, we have a menu with thumbnails that allows us to walk through different panes. All this information has been picked up from the metadata imported from DB2 into the project.

256

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-16 NULLID.DEPT table overview

The table NULLID.DEPT has five columns and two foreign keys defined. Column DEPTNO has been defined as a primary key. At first glance the definition seems to be OK. By clicking the Columns pane (Figure 11-17), we can obtain more information about the individual columns.

Figure 11-17 NULLID.DEPT table columns

The information shown in Figure 11-17 is for the DEPTNO column. It is probably a good idea to browse through all columns and look at their definitions to get a better feel for this. Switch to the Primary Key tab. This takes us to Figure 11-18 on page 258, which shows the primary key settings.

Chapter 11. Sample application

257

Figure 11-18 NULLID.DEPT table Primary Key

Adjustments can be made, but in our case this is not required. Click the Foreign Key tab. The information about foreign keys, displayed in Figure 11-19, is quite interesting.

Figure 11-19 NULLID.DEPT table foreign keys

It shows a foreign key REMP relationship between the MGRNO column in table NULLID.DEPT, and the primary key field in table NULLID.EMP.

258

DB2 for z/OS and WebSphere: The Perfect Couple

RSELFD is a second referential relationship corresponding to column ADRMDEPT in table NULLID.DEPT and related to the primary key field of the same table. We can look at the other two tables in a similar way. Our development experience shows that we may have a problem with the EMP_PHOTO_RESUME table. Open EMP_PHOTO_RESUME.tblxmi (Figure 11-20).

Figure 11-20 Columns of EMP_PHOTO_RESUME table

Select the Columns tab (Figure 11-20). The EMP_ROWID column is interpreted as a BLOB data type by WSAD (not the ROWID data type). Because we do not use this column in any of our queries directly, we can safely delete the EMP_ROWID column. (In addition, having the wrong data type is likely to cause problems during the generation process as well.) Restriction: Normally the presence of the ROWID should be transparent for the CMP generation, but currently this is a work-around. We are ready now for the next step, building the EJBs. Using bottom-up mapping from the relational database model, we build one CMP entity EJB for each table.

From a relational database (RDB to EJB)


In this step we generate the four basic EJB artifacts for each table. As the EJBs will be used locally within the same container, only local homes (objects) will be generated. For each entity EJB we will have a: LocalHome LocalObject Bean Primary Key The existing deployment descriptor ejb-jar.xml of the EJB project will also be updated.

Chapter 11. Sample application

259

Make sure to be in a J2EE perspective, and have (in the left-upper corner) the Project Navigator view active. Put the focus on the ItsoEJB1 project. Right-click Generate EJB to RDB Mapping, as shown in Figure 11-21.

Figure 11-21 RDB to EJB Mapping

A first window (see Figure 11-22) pops up. We accept the defaults, and click Next.

Figure 11-22 Back-end folder

Again, we accept the default on the next window (Figure 11-23). The EJB construction will be done bottom-up. The starting point is the table metadata, because these are EJBs for existing tables. Click Next.

Figure 11-23 Mapping bottom-up

This takes us to the window shown in Figure 11-24 on page 261.

260

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-24 CMP type2.0 and name prefix

Some information on this panel is crucial. Although older 1.1 CMP Beans still can be generated, but go the 2.x way, as only this type offers the new facilities. We also specify the project folder in which we like the EJB code to be packaged and a prefix that will be put in front of the artifact names. Click Finish. The mapping is now being created, and will complete after a while. We can verify a few things of interest. When the generation completes, the overview map is opened automatically (Figure 11-25), and we can look at mappings between the DB2 attributes and the properties of the CMP Beans.

Figure 11-25 Map.mapxmi

Interesting to look at are the files prepared by the CMP generation process. We can look at them from different perspectives. Let us try using a Java perspective, as shown in Figure 11-27 on page 262.

Chapter 11. Sample application

261

Figure 11-26 Files generated by EJB to RDB Mapping

In the ItsoEJB1/ejbModule project folder, we find a newly created package ejb.empl, in which we distinguish three groups of Java files (one group for each EJB). Each group is composed of four files (Bean, Key, LocalHome, Local (object)). The Beans that have been generated here can only be used via a local reference. (We did not select the option for remote reference.) This is new in EJB2.0. Let us have a quick look at the generated code, for example, for the DEPT table (Figure 11-27).
local hom e/interface ITSO DeptLocalH om e

bean/class ITSO DeptBean

finder
prim arykey/class IT SO DeptKey

lifecycle m ethods

local/interface ITSO DeptLocal

m p ro

o tio

Figure 11-27 Generated code for DEPT table

262

DB2 for z/OS and WebSphere: The Perfect Couple

Attention: Local means that the caller (in our case the session Bean and the EJBs that are called), the entity Beans, has to reside in the same Java Virtual Machine (JVM). In the Figure 11-27 on page 262 you recognize the generated Java classes and interfaces for Bean DEPT. In the local/interface and Bean/class we find the same accessors (setters and getters). The accessors have been automatically promoted to the local interface. We also see the localhome/interface, which currently only has one finder method. More finders could be added or generated, so that the Bean can be approached by other means than its primary key. By opening (double-clicking) the file ITSODeptBean.java, we discover that accessors (getters and setters) have been generated for all table columns, except the columns ADMRDEPT and MGRNO, which are used as foreign keys to the DEPTNO (primary key in this DEPT) and EMPNO (primary key in EMP), but we find four additional accessors for EMP, DEPT, RSELFD, and REMP. The signatures of the methods clearly show what is obtained through those getters. The useful getters are:
public abstract ejb.empl.ITSODeptLocal getRselfd();

The previous signature is an abstract declaration for method getRselfd, which is the result of the referential integrity definition between field ADMRDEPT in table DEPT and the primary key of the same table DEPT. The method returns a local DEPT object, which is the administrative department this DEPT belongs to.
public abstract java.util.Collection getDept();

This signature is an abstract declaration for method getDept, which is also the result of the referential integrity definition between field ADRMDEPT in table DEPT and the primary key of the same table DEPT. The method returns a collection of local DEPT objects, all administered by this department.
public abstract ejb.empl.ITSOEmpLocal getRemp();

The previous signature is an abstract declaration for method getRemp, which is the result of the referential integrity definition between field MGRNO in table DEPT, and the primary key of table EMP. The method returns the local EMP object corresponding to the MGRNO as an employee attribute (EMPNO) in table EMP.
public abstract java.util.Collection getEmp();

This signature is an abstract declaration for method getEmp, which is a result of the referential integrity definition between field WORKDEPT in table EMP and table DEPT. The method returns a collection of local EMP objects, all belonging to the same WORKDEPT. By double-clicking the ITSOEmpBean.java file, we see that accessors (getters and setters) have been generated for all table columns, except the column WORKDEPT, which is used as a foreign key to the DEPTNO (primary key in DEPT). However, we find two additional accessors groups for DEPT and RDEPT. The useful getters are:
public abstract ejb.empl.ITSODeptLocal getRdept();

The previous signature is an abstract declaration for method getRdept, which is a result of the referential integrity definition between field WORKDEPT in table EMP and table DEPT. The method returns a local DEPT object corresponding to the WORKDEPT attribute in EMP as a department attribute (DEPTNO).
public abstract java.util.Collection getDept();

Chapter 11. Sample application

263

The previous signature is an abstract declaration for method getDept, which is the result of the referential integrity definition between field MGRNO in table DEPT and table EMP. The method returns a collection of local DEPT objects, all managed by the same MGRNO. When we switch to a J2EE perspective, and we look to the outline view (Figure 11-28) in the left bottom corner, while we have the ITSOEmpBean Java code displayed in the right-upper pane, we see that the getEmpno() method available in the Bean has not been promoted to the local interface. The getEmpno() method should have the indication L in front to indicate that it was promoted. We will do this manually. To do so, put focus on the getEmpno() method in the outline view, right-click Enterprise Bean Promote to Local Interface.

Figure 11-28 Outline view of table EMP

The same operation also has to be performed for the getDeptno() method on the ITSODeptBean and getEmpno() on the ITSOEmp_photo_resumeBean. Accessing the individual attributes of the CMP Bean one by one via the local interface is not the most efficient way of working. Each access to a getter could trigger the start of a transaction if the transactional attribute of the EJB method was not set correctly. To accommodate this problem we will use data transfer JavaBeans, which will transit between the CMP Bean and our application code and by which we can get all the information from the CMPBean in one operation. To do so, we add an additional business method to each Bean, getDepartment(deptno) for the ITSODeptBean, gand etEmployee(empno) for the ITSOEmpBean, returning all information in one JavaBean. These methods must also be promoted to the local interfaces on the Outline view. The Java classes for the data transfer must also be added, or made available through a linkage to a utility project ItsoUtil. We also add a business method getImage() (see Example 11-1) in the ITSOEmp_photo_resumeBean.java class, and this has to be promoted to the object class ITSOEmp_photo_resumeLocal.java as well. This corresponds to a getter on the getBmp_photo attribute, and expresses better what we want to acquire.
Example 11-1 getImage() method public byte[] getImage() { return getBmp_photo(); }

264

DB2 for z/OS and WebSphere: The Perfect Couple

In Example 11-2 we show the data transfer Bean Java code for the department. From a theoretical point of view this is a real Bean. It has properties for which setters and getters are defined. The Bean also implements the Serializable interface. It is located in project ItsoUtil.
Example 11-2 empl.Department package empl; /** * department class for SG24-6319 */ public class Department implements Serializable { public String deptno; public String deptname; public String location; public String mgrno; public String admrdept; public String getAdmrdept() { return admrdept; } public String getDeptname() { return deptname; } public String getDeptno() { return deptno; } public String getLocation() { return location; } public String getMgrno() { return mgrno; } }

The new business method that has been added in the ITSODeptBean looks like Example 11-3.
Example 11-3 Business method for getting Department information public empl.Department getDepartment() { System.out.println("++ITSODeptBean_getDepartment"); empl.Department department = new empl.Department(); department.deptno = getDeptno(); department.deptname = getDeptname(); department.location = getLocation(); department.mgrno = getRemp().getEmpno(); department.admrdept = getRselfd().getDeptno(); return department; }

The actions required for the Emp table are similar, and are not explained in more detail.

Looking at and changing the deployment descriptor


The deployment descriptor of an EJB project is an essential part of the project. This XML file located in the folder META-INF is named ejb-jar.xml. Originally it was empty, created together with the EJB project. It has been updated by the WSAD actions and import of the tables. It contains basically one section for each entity Bean with references to the attributes (container-managed persistence fields) of the mapped tables. As an example we show the

Chapter 11. Sample application

265

section for the EMP Bean in Example 11-4 (not all CMP fields are shown). This was completely generated by the importing wizard.
Example 11-4 CMP definitions for EMP table <entity id="ContainerManagedEntity_1076976661213"> <ejb-name>Emp</ejb-name> <local-home>ejb.empl.ITSOEmpLocalHome</local-home> <local>ejb.empl.ITSOEmpLocal</local> <ejb-class>ejb.empl.ITSOEmpBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>ejb.empl.ITSOEmpKey</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>Emp</abstract-schema-name> <cmp-field id="CMPAttribute_1076976661303"> <field-name>empno</field-name> </cmp-field> <cmp-field id="CMPAttribute_1076976661313"> <field-name>firstnme</field-name> </cmp-field> <cmp-field id="CMPAttribute_1076976661314"> <field-name>midinit</field-name> </cmp-field> <cmp-field id="CMPAttribute_1076976661323"> <field-name>lastname</field-name> </cmp-field> ............................. <cmp-field id="CMPAttribute_1076976661404"> <field-name>comm</field-name> </cmp-field> </entity>

The imported metadata also describe relationships between the tables. As a consequence, WSAD also adds relation description sections to the deployment descriptor, through the usage of container-managed relation (CMR) fields. This is new in CMP 2.0. As an illustration, Example 11-5 shows the section that is the result of the relationship (RDEPT foreign key) from the EMP table (column WORKDEPT) to the DEPT tables primary key.
Example 11-5 CMR definitions for EMP table->DEPT table relationship <ejb-relation> <ejb-relation-name>Emp_To_Dept</ejb-relation-name> <ejb-relationship-role id="EJBRelationshipRole_1076976661413"> <ejb-relationship-role-name>rdept</ejb-relationship-role-name> <multiplicity>Many</multiplicity> <relationship-role-source> <ejb-name>Emp</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>rdept</cmr-field-name> </cmr-field> </ejb-relationship-role> <ejb-relationship-role id="EJBRelationshipRole_1076976661414"> <ejb-relationship-role-name>emp</ejb-relationship-role-name> <multiplicity>One</multiplicity> <relationship-role-source> <ejb-name>Dept</ejb-name> </relationship-role-source> <cmr-field>

266

DB2 for z/OS and WebSphere: The Perfect Couple

<cmr-field-name>emp</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> </ejb-relationship-role> </ejb-relation>

Figure 11-29 shows the relationship in a picture. As a result of the CMR definitions, we have a getEmp() method on the Dept object and a getRdept() method on Emp. The property names come from the CMR names.

rdept(getRdept())

0..m
Emp

workdept empno deptno

0..1
Dept Emp
empno

Emp
empno

emp(getEmp())

Figure 11-29 A department can have 0..m employees (0..1->0..m)

Another way to look at those relationships starts from the Beans tab of the deployment descriptor window. Open the deployment descriptor with its built-in editor by double-clicking the XML file. Then select the Beans tab and scroll to the relationships section, and expand the Emp-to-Dept relationship (Figure 11-30).

Figure 11-30 Beans - Relationships Chapter 11. Sample application

267

Click Edit on the relationship that you want yo look at, and then Next. A window like Figure 11-31 should appear. Note the characteristics of this relationship: Multiplicity: Defines whether an object or a collection is returned CMR field referencing: Determines the property name (emp on Dept, rdept on Emp)

Figure 11-31 Defined relationship between Emp-Dept

We will now extend the deployment descriptor with EJB Query Language (EJBQL). This query tool is available since specification EJB 2.0. We will use it to have an additional find facility by Name on the EMP table through the CMP Bean. To achieve this, we must complete two tasks:

Adding the EJBQL statement description to the deployment descriptor Defining an additional finder in the ITSOEmpLocalHome.java interface
EJBQL statements belong to a particular entity Bean, and must be defined in a <query> section, inside the <entity> Bean scope. Example 11-6 shows the EJBQL description that has to be added inside the Entity section of the EMP Bean. To add the statement, you can directly edit the deployment descriptor XML file (Source tab), or use the Add button of the query section in the Beans tab of the deployment descriptor in WSAD.
Example 11-6 EJBQL statement in the deployment descriptor <entity id="ContainerManagedEntity_1076532486891"> <ejb-name>Employee</ejb-name> .......... <query> <description>EJBQL query for employees in 1 department</description> <query-method> <method-name>findByLastName</method-name> <method-params>

268

DB2 for z/OS and WebSphere: The Perfect Couple

<method-param>java.lang.String</method-param> </method-params> </query-method> <ejb-ql>SELECT OBJECT(e) FROM Emp e WHERE e.lastname like ?1</ejb-ql> </query> </entity>

The additional finder that has to be added to the ITSOEmpLocalHome is shown in Example 11-7.
Example 11-7 Finder in ITSOEmpLocalHome.java /** * Finds instances by Lastname(via like): */ public java.util.Collection findByLastName(java.lang.String lastname) throws javax.ejb.FinderException;

After adding this finder, it may be a good idea to add an index on the lastname column, for performance reasons.

Completing the deployment descriptor


Additional information has to be provided to the EJB project. This is done through the wizards available for the deployment descriptor. This again has to be repeated for each entity Bean. We will walk through the different parts of the wizards. We open the deployment descriptor with its specialized editor by double-clicking, and see the first panel labeled Overview (Figure 11-32).

Figure 11-32 Deployment descriptor - Overview

Chapter 11. Sample application

269

Note the presence of the three entity EJBs. At the bottom, we have several tabs to walk through the different parts of the deployment descriptor. We select the Beans one by one, and make the required additions. We first select the Dept Bean by clicking it (Figure 11-33).

Figure 11-33 Dept CMP entity Bean

The most important information to add at this moment is the binding information for JDBC to access DB2 data (WebSphere Bindings). This information is indirect; it is a reference to a resource definition that is assumed to be available in the WAS V5 servers (containers) that will be running this application. We use the name jdbc/ITSO1. This name can be changed at deployment. We set the container authorization type to Container. Connections to the data will be authorized based on the container (thread) (or in some cases the component JAAS alias will be used). Each EJB also has a lookup name (JNDIname) with which it can be found in the name space. We simplify this name by taking off the first ejb. We repeat the operation for the two other Beans and save the descriptor. Note: JDBC lookup names should by convention start with jdbc/. EJB lookup names should by convention start with ejb/.

Generating the deployment code for the CMP Beans


All required changes have been made to the four initial EJB artifacts and the deployment descriptor. We are now ready for the last step of the entity Beans preparation, the generation of the Stub/Skeleton code. Verify that you are in a J2EE perspective and have in the left upper corner of the Project Navigator view active. Put focus on the ItsoEJB1 project, and right-click Generate Deployment and RMIC code (Figure 11-34 on page 271).

270

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-34 Deployment and RMIC code

Additional classes are created by the wizard. Some of those classes are a concrete implementation of the abstract definitions in the original Bean classes. Also, additional finders are now available. Those are visible in the concrete classes and have been promoted to EJSLocalCMPxxxHome classes, which implement the original LocalHome interface. We will have a look to those new finders for the Dept table (Figure 11-35). We are not supposed to make any changes to the generated Java code. To see these additional classes, it is best to switch to the Java perspective/package explorer view.

LocalH om e interface

LocalH om e im plem entation

new finders

Figure 11-35 Added finders for CMR

The additional finders are a result of the CMR definitions in the deployment descriptor. The most useful finders for the Dept Bean are:
public ejb.empl.ITSODeptLocal findByPrimaryKey_Local(ejb.empl.ITSODeptKey primaryKey) public java.util.Collection findDeptByRempKey_Local(ejb.empl.ITSOEmpKey key) public java.util.Collection findDeptByRselfdKey_Local(ejb.empl.ITSODeptKey key) Chapter 11. Sample application

271

The EMPBean also got an additional finder as a result of the RDEPT relation:
public java.util.Collection findEmpByRdeptKey_Local(ejb.empl.ITSODeptKey key)

The next additional finder is a result of the EJBQL statement that we defined:
public java.util.Collection findByLastName_Local(java.lang.String lastname)

The only finder that we should use directly is the one that we added for EJBQL. All others are internal, and used implicitely by the getters and setters added as a result of the CMR fields. This concludes the preparation of the three CMP Beans for the imported tables: Dept JNDIname (ejb.empl.ITSODeptLocalHome) Emp JNDIname (ejb.empl.ITSOEmpLocalHome) Emp_photo_resume JNDIname (ejb.empl.ITSOCMPEmp_photo_resume) All three are part of one EJB project included in the EAR file called Itso1EAR.

Packages for EJBs


When we have a closer look at the Java packages that exist now for the EJBs (Figure 11-36), we discover what is shown in Figure 11-31 on page 268.

Figure 11-36 Java packages

Besides the general supporting packages, whose names start with com.ibm., and org.omg., we find three packages starting with ejb.empl related to the entity Beans. Two packages are general, while the third one seems to be back-end related. We conclude that we could have generated code for other back-ends in the same project. The differences are concentrated in one package, while the other packages are common. To find out what is specific to this package, we can open file ITSOEmpBeanFunctionSet_f2676a0f.java, for example. In this file you find the JDBC code for the (Create, Retrieve, Update, Delete (CRUD)) methods, and as we started from tables with a NULLID qualifier, the table references in the statements are unqualified.

Binding the tables to a qualifier


The real table names that we use in the DB2 for z/OS have a qualifier ITSOUSER. The access to DB2 will have to be qualified through information in the data source definition. This also explains how it is possible to have several data source definitions with the same properties, referencing the same DB2, but with different SQLIDs or qualifiers. The specification of the current SQLID is via the currentSQLID custom property that you can specify at the Data Source level. See 3.5.2, Defining Data Sources under this provider on

272

DB2 for z/OS and WebSphere: The Perfect Couple

page 57, and Figure 3-18 on page 64 for more details on how to specify datasource custom properties.

11.2.2 Container-managed persistence entity Beans with SQLJ


In this part we will build a CMP Bean using SQLJ. To show an alternative approach of how to get non-qualified table schemas, after importing a qualified table, we start the import process using the set of tables that are qualified with ITSOUSER (not NULLID as was the case in the previous sections). In the previous sections, we used JDBC for the CMP Beans. SQLJ can also be used with CMP Beans. We now show how to build a new CMP Bean for the EMP_PHOTO_RESUME table. To do so, we use a new EJB project, ItsoEJBPhotoCMPSQLJ. To create this EJB project and perform the other activities that are the same as for the CMP/JDBC case, see 11.2.1, Creating entity CMP Beans using JDBC from the imported tables on page 253. We import the table ITSOUSER.EMP_PHOTO_RESUME, as before, under the subdirectory ejbModule of the new project. At this point we have a structure under the backends in the project that points to the qualifier ITSOUSER (Figure 11-37).

Figure 11-37 Changing qualifier

Put the focus on the ITSOUSER subdirectory (by clicking it), right-click, select Rename, and change to NULLID. As before, in the Data Perspective in the Navigator view, drill down in the file hierarchy under the project/ejbModule/META-INF/backends to the NULLID.EMP_PHOTO_RESUME.tblxmi file, and open it by double-clicking. In the window on the right that shows up, go to the Columns pane and delete the column EMP_ROWID. We never use this column in any query, and it causes problems in the generation process. After this, save the file. We now switch to a J2EE perspective, and we generate the four base classes of the CMP Bean by putting focus on the ItsoEJBPhotoCMPSQLJ project, right-click, select Generate EJB to RDB mapping. To be able to distinguish the new EJB from the existing CMP version, we use as a prefix ITSOSQLJ. At this time we have four classes/interfaces generated, and the file Map.mapxmi was opened in the right pane.

Chapter 11. Sample application

273

Before continuing we have to prepare the project/backend for using SQLJ instead of JDBC. When you highlight the project name in the middle subpane of the Map.mapxmi panel for this backend (see Figure 11-38), the bottom part shows the properties that will be used during the generation of the code.

Figure 11-38 Changing the SQLJ option

In the Properties pane at the bottom, expand the SQLJ line, and change the value from false to true, and then save the map. The project itself must also be enabled for SQLJ. To do so, highlight the project, right-click, and in the pull-down list select Add SQLJ Support. This creates an additional subdirectory SQLJAntScripts under the project. Note: Ant (a command script language build into WSAD) will drive the program preparation and package bind process on the host for SQLJ. The last change to make before generating the deployment code is, like before, to add our business method getImage() in the ITSOSQLJEmp_photo_resumeBean.java class, and also promote it to the object class ITSOSQLJEmp_photo_resumeLocal.java. Save both classes. Now we can generate the deployment code for the CMP/SQLJ Bean by highlighting the project, right-clicking, and selecting Generate Deployment and RMIC code. This time more additional classes are generated. They are related to the SQLJ access. We find in our project, among others, the subdirectory (see Figure 11-39 on page 275) websphere_deploy.ItsoEJBPhotoCMPSQLJ.DB2UDBOS390_V7_1. It contains sqlj code, which was directly translated in Java code. During this translation, a .ser file (a serialized profile, which is a serialization of the class sqlj/runtime/profile/Profile) was also created. This

274

DB2 for z/OS and WebSphere: The Perfect Couple

serialized profile, FS_DBD8_SJProfile0.ser, contains an entry for each SQL statement that has been created for the CMP Bean by the deployment generator. It is the input for the profile customization process, which (by default) drives the creation of the packages (with static SQL) on the system (z/OS), where finally everything will be deployed and run. (It is possible to split the customization process and bind process into two steps if required.)

Figure 11-39 Sqlj and Java code after translation

The EJB code is now generated for SQLJ, but (as outlined in 7.2, Profile customization on page 146) additional steps are required to turn SQLJ programs into real static SQL. Those additional steps can be executed from within WSAD under the guidance of an Ant script. Note: An Ant script is the equivalent of a Make file but for Java preparation.

Preparation of the Ant script


The Ant script needs a skeleton. It can be generated as follows. Highlight the project, right-click Properties SQLJ Customization script, and fill in as indicated in Figure 11-40.

Figure 11-40 skeleton of the Customization script

Chapter 11. Sample application

275

The db2 profile customization process (db2sqljcustomize) uses a type 4 connection to the DB2 system (DBD8). Therefore we need to specify a URL with a host name, port number, and DB2 location name. If you want, you can also specify additional (bind) parameters, such as a collection name you want the package to be bound into. url Options jdbc:db2://wtsc65.itso.ibm.com:38070/DBD8 -COLLECTION SG246319

The DB2 packages that will be created should all be grouped under a common collection. This a value that we can choose, but it should remembered. Click OK. A file sqlj.project.properties is created under the SQLJAntScripts directory in the project. Highlight the project, right-click, and select Generate SQLJ Customization script. This step changes sqlj.project.properties created in the previous step, but also added a new file sqlj.customize.xml, which contains input for the Ant utility (Figure 11-41).

Figure 11-41 Additions for SQLJ under SQLJAntScripts directory

Highlight the project again, right-click, and select Properties SQLJ Customization script (Figure 11-42).

Figure 11-42 SQLJ Customization script after

In Figure 11-42 the name of the serialized profile was added together with a proposed (default) package prefix of maximum seven characters, because one package will be generated for each of the four isolation levels and a 14 will be appended to the name. We change this name to avoid conflicts with other package names. We change to CPHOEMP. Note that, besides the COLLECTION, we added additional parameters QUALIFIER and BINDOPTIONS. This is additional information for the bind process, since we have unqualified SQL statements (see the FS_DBD8.sqlj member of this backend, for example). With these bind options, the unqualified table names in the SQL statements are prefixed with the ITSOUSER qualifier. Click OK to save. At this point we are ready to run the Ant utility for the customization script through a type 4 connection, and generate the packages in the specified collection. 276
DB2 for z/OS and WebSphere: The Perfect Couple

Highlight the sqlj.customize.xml file, right-click, and select Run Ant. On the first panel that shows up (Figure 11-43), switch to the Properties pane.

Figure 11-43 Target pane from Ant

Here we use the Add button on the right side to add additional properties required for a successful bind on DB2 z/OS. Add the following: db.user: BARTR1 db.password: xxxxxxx

Chapter 11. Sample application

277

Figure 11-44 Properties pane

When this is done, click Run. The output of the bind should be similar to the output shown in Example 11-8.
Example 11-8 Binding of the SQLJ packages Buildfile: C:\itsosj\IBM\wsappdev51\workspace\ItsoEJBPhotoCMPSQLJ\SQLJAntScripts\sqlj.customize.xml websphere_deploy.ItsoEJBPhotoCMPSQLJ.DB2UDBOS390_V7_1.FS_DBD8: [java] [ibm][db2][jcc][sqlj] [java] [ibm][db2][jcc][sqlj] Begin Customization [java] [ibm][db2][jcc][sqlj] Loading profile: websphere_deploy\ItsoEJBPhotoCMPSQLJ\DB2UDBOS390_V7_1\FS_DBD8_SJProfile0 [java] [ibm][db2][jcc][sqlj] Customization complete for profile ..\ejbModule\websphere_deploy\ItsoEJBPhotoCMPSQLJ\DB2UDBOS390_V7_1\FS_DBD8_SJProfile0.ser [java] [ibm][db2][jcc][sqlj] Begin Bind [java] [ibm][db2][jcc][sqlj] Loading profile: websphere_deploy\ItsoEJBPhotoCMPSQLJ\DB2UDBOS390_V7_1\FS_DBD8_SJProfile0 [java] [ibm][db2][jcc][sqlj] Driver defaults(user may override): BLOCKING ALL VALIDATE BIND [java] [ibm][db2][jcc][sqlj] Fixed driver options: DATETIME ISO DYNAMICRULES BIND [java] [ibm][db2][jcc][sqlj] Binding package CPHOEMP1 at isolation level UR [java] [ibm][db2][jcc][sqlj] Binding package CPHOEMP2 at isolation level CS [java] [ibm][db2][jcc][sqlj] Binding package CPHOEMP3 at isolation level RS [java] [ibm][db2][jcc][sqlj] Binding package CPHOEMP4 at isolation level RR [java] [ibm][db2][jcc][sqlj] Bind complete for websphere_deploy\ItsoEJBPhotoCMPSQLJ\DB2UDBOS390_V7_1\FS_DBD8_SJProfile0 customizeAll: BUILD SUCCESSFUL Total time: 3 seconds

When everything runs fine, four packages for different Isolation levels are created on the DB2 for z/OS system (DBD8).

278

DB2 for z/OS and WebSphere: The Perfect Couple

This concludes preparation of the CMPSQLJ project for the table EMP_PHOTO_RESUME with qualifier ITSOUSER. The generated SQLJ code is located in websphere_deploy.ItsoEJBPhotoCMPSQLJ.DB2UDBOS390_V7_1.FS_DBD8.sqlj. When we open this file, we clearly see the SQL instructions, which are unqualified.

Completing the deployment descriptor


The deployment descriptor ejb-jar.xml has to be completed as before. We open de ejb-jar.xml file by double-clicking. Select the Beans tab and highlight Emp_Photo_resume. The properties of this Bean should now show up as in Figure 11-45.

Figure 11-45 Beans panel for Emp_photo_resume

The information to add is the binding information for JDBC/SQLJ. This information is indirect. It is a reference to a resource definition that is assumed to be available in the WAS V5 servers (containers) running this application. We select the name jdbc/ITSO1. This name can be changed at deployment time if required. Again, we set the container authorization type to Container. Each EJB also has a lookup name (JNDIName) with which it can be found in the name space. We simplify this name by taking off the first ejb. We should now be able to use this PhotoBean also in the model from within the session Bean. Emp_photo_resume: JNDIname (ejb.empl.ITSOCMPSQLJEmp_photo_resume) This CMP/EJB project is also included in EAR Itso1EAR.

Chapter 11. Sample application

279

11.2.3 Bean and container-managed persistence entity Bean with SQLJ


We have also included in the J2EE application a project ItsoEJBSqlj, which contains: A BMP/SQLJ Bean for table ITSOUSER.EMP A CMP/SQLJ Bean for tables ITSOUSER.EMP and ITSOUSER.DEPT The preparation of those Beans, together with the explanation, is provided in Chapter 7, SQLJ on page 139.

11.2.4 Bean-managed persistence entity Beans with JDBC


In this section we build a Bean-managed persistence (BMP) Bean with JDBC for the table EMP_PHOTO_RESUME. Entity Beans can be built with container-managed persistence but also Bean-managed persistence (BMP). In other words, the persistence code has to be written by the developer, and is not generated by the container. Nevertheless, the BMP entity Bean has to respect the life-cycle methods imposed by the J2EE specs. In this section we show how to create a BMP Bean that is looking for the photo of an employee. It is the counterpart of the CMP/JDBC ITSOEmp_photo_resumeBean in project ItsoEjb1. In the life-cycle methods, also called the callbacks, appropriate actions have to be taken to access the DB2 data. Those actions can be written in JDBC or in SQLJ.

BMP with JDBC


For this EJB we also create a separate EJB project ItsoEJBPhotoBMP. The new EJB project should also be part of the J2EE application Itso1EAR. In this project we build a BMP Bean. The skeleton of the new BMP Bean can be prepared with a WSAD wizard. Being in a J2EE perspective, with a J2EE hierarchy view in the left top pane, highlight the ItsoEJBPhotoBMP project, right-click, and select New Enterprise Bean (Figure 11-46).

Figure 11-46 Enterprise Bean creation

Next, enter/select the project (Figure 11-47 on page 281).

280

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-47 New Bean in project

Click Next and you will get a new pop-up for selecting the type of Bean (Figure 11-48).

Figure 11-48 Give a name to the Bean

Select Entity BMP, and specify the Bean name, Source folder, and Default package as indicated above. Click Next and go to the window shown in Figure 11-49.

Figure 11-49 Selecting local or remote interfaces

Chapter 11. Sample application

281

Since the EJB 2.0 specification, EJBs can have local and remote interfaces. Leave the panel as is, with only the local interface selected, and click Finish. Note: Both interfaces are possible. The remote interfaces use the Object Request Broker; the caller and the object that is called can reside in separate containers. With local interfaces both reside in the same container, or in practice in the same Java Virtual Machine (JVM). Four Java files are created in the package ejb.empl, as indicated in Figure 11-50.

Figure 11-50 Java files created

Besides this, the META-INF information (deployment descriptor ejb-jar.xml, IBM extensions, etc.) has also been prepared. All those files have to be completed. The difference between the CMP approach and the BMP approach is that in this case (BMP) those files are only placeholders and the code has to be written manually. The first file we tackle is PhotoEmployeeBMPKey.java, shown in Example 11-9.
Example 11-9 PhotoEmployeeBMPKey class package ejb.empl; /** * Key class for Entity Bean: PhotoEmployee */ public class PhotoEmployeeBMPKey implements java.io.Serializable { static final long serialVersionUID = 3206093459760846163L; /** Implementation field for key attribute: photo_format */ //public java.lang.String photo_format; public PhotoEmployeeBMPKey() { } /** Implementation field for key attribute: empno */ public java.lang.String empno; /** Creates a key for Entity Bean: Employee */ public PhotoEmployeeBMPKey(java.lang.String empno) { this.empno = empno; } /** Creates a key for Entity Bean: Employee,Emp_photo */ public boolean equals(java.lang.Object otherKey) { if (otherKey instanceof ejb.empl.PhotoEmployeeBMPKey) { ejb.empl.PhotoEmployeeBMPKey o = (ejb.empl.PhotoEmployeeBMPKey) otherKey; return (super.equals(otherKey)); } return false; } /** Returns the hash code for the key. */ public int hashCode() { return (super.hashCode());

282

DB2 for z/OS and WebSphere: The Perfect Couple

} }

The PhotoEmployeeBMPKey program contains the reference to the primary key of the PhotoEmployee table. The key Empno is a string of six characters. Figure 11-51 shows a schematic representation of a BMP Bean. We recognize the artifacts. The object and home can exist in local and remote versions. This makes a total of six.

local/remote home
create

bean
ejbCreate ejbPostCreate

client

ORB
by reference

te mo re al loc

findbyPrimaryKey find...

ejbFindbyPrimaryKey ejbFind...

local/remote object

ejbLoad ejbStore ejbRemove

lifecycle callback methods

loc al re mo te

business methods

setters getters

business methods setters getters

primarykey

Figure 11-51 The six original BMP classes/interfaces

In our scenario we only use local versions. Note: Clients allways access the API on the home for finders and creation, and on the object for business methods, which include setters/getters and whatever methods are provided. All business methods are implemented on the Bean, but those that have to be used from a client must be promoted on the object. The so-called life-cycle methods require a compulsory implementation on the Bean. Those methods are driven by the container when needed. What does it mean in practice? The create, finder methods on the home have a corresponding EjbCreate, EjbFinder on the Bean. The callback methods that are automatically invoked by the EJB container must be present on the Bean and coded to fulfill their role as expected. In this design an entity Bean reflects the contents of one row in a relational database. EjbCreate() EjbLoad() EjbStore EjbRemove() -> Create a new row. -> Load the row. -> Update the row. -> Delete the row.

All business methods (our methods) that we like to invoke must be present on the Bean and promoted to the object interface. For example, we would like to have a method

Chapter 11. Sample application

283

getImage() to get the image of an employee. The method must be written on the Bean and then promoted to the object interface. The Java code for the other BMP sources is shown hereafter. The local home interface (Example 11-10) has two lifecycle methods defined: create() and findByPrimaryKey(). In the Bean, we find the counterparts of the methods with ejb in front.
Example 11-10 Local home interface package ejb.empl; /** * Local Home interface for Enterprise Bean: PhotoEmployeeBMP */ public interface PhotoEmployeeBMPLocalHome extends javax.ejb.EJBLocalHome { /** * Creates an instance from a key for Entity Bean: PhotoEmployeeBMP */ public ejb.empl.PhotoEmployeeBMPLocal create() throws javax.ejb.CreateException; /** * Finds an instance using a key for Entity Bean: PhotoEmployeeBMP */ public ejb.empl.PhotoEmployeeBMPLocal findByPrimaryKey( ejb.empl.PhotoEmployeeBMPKey primaryKey) throws javax.ejb.FinderException; }

The local interface (Example 11-11) has one business method defined: getImage(). This is a result of the promotion of the method from the Bean.
Example 11-11 Local interface package ejb.empl; /** * Local interface for Enterprise Bean: PhotoEmployeeBMP */ public interface PhotoEmployeeBMPLocal extends javax.ejb.EJBLocalObject { public byte[] getImage(); }

Notice that in Example 11-12, the life-cycle callback methods start with Ejb. As mentioned, the presence of these methods is mandatory, even though there is no code associated with the non-select part. The getImage() method, which is the business method in this Bean, requires the promotion to the object. The getImage() method returns the BLOB, a picture of the employee. The access to DB2 is using JDBC. You can also see that the SQL select statement is unqualified.
Example 11-12 BMP Bean package ejb.empl; //import empl.G5Exception; /** * Bean implementation class for Enterprise Bean: PhotoEmployee */ public class PhotoEmployeeBMPBean implements javax.ejb.EntityBean { private javax.ejb.EntityContext myEntityCtx; private boolean debugOn = true; static final String emplphotozos = "SELECT EMPNO, BMP_PHOTO FROM EMP_PHOTO_RESUME WHERE EMPNO = ?";

284

DB2 for z/OS and WebSphere: The Perfect Couple

private javax.sql.DataSource ds; private byte[] imagebytes; private String empno; private java.sql.Connection conn; private java.sql.PreparedStatement pstmt; private ejb.empl.PhotoEmployeeBMPKey prikey; private String imagetype = "gif"; private static String dsname = "ITSODB2"; // <========== initialize dsname ====== private java.sql.Blob image; boolean isModified; /** * ejbActivate */ public void ejbActivate() { } /** * ejbLoad */ public void ejbLoad() { //if (this.imagebytes != null) // return; java.sql.ResultSet rs = null; ejb.empl.PhotoEmployeeBMPKey prikey = (ejb.empl.PhotoEmployeeBMPKey) myEntityCtx.getPrimaryKey(); String empno = prikey.empno; System.out.println("++PhotoEmployeeBMPBean_ejbLoad " + empno); try { conn = ds.getConnection(); rs = selectByPrimaryKey(empno); if (rs != null) { if (!rs.next()) { System.out.println( "++PhotoEmployeeBMPBean_ejbLoad NO photo"); } else { if (this.debugOn) System.out.println( "++PhotoEmployeeBMPBean_ejbLoad extracting photo"); do { java.sql.Blob image; image = rs.getBlob(2); if (image != null) { this.imagebytes = image.getBytes((long) 1, (int) image.length()); if (this.debugOn) System.out.println( "++PhotoEmployeeBMPBean_ejbLoad photolength " + this.imagebytes.length); } else { System.out.println( "++PhotoEmployeeBMPBean_ejbLoad getBlob() returned NULL"); } } while (rs.next()); } rs.close(); } pstmt.close(); conn.close(); } catch (java.sql.SQLException ex) { System.out.println( "++PhotoEmployeeBMPBean_ejbLoad SQLException " + ex.toString());

Chapter 11. Sample application

285

throw new javax.ejb.EJBException( "++PhotoEmployeeBMPBean_ejbLoad SQL error " + ex.getMessage()); } catch (Exception ex) { System.out.println( "++PhotoEmployeeBMPBean_ejbLoad Exception " + ex.toString()); throw new javax.ejb.EJBException( "++PhotoEmployeeBMPBean_ejbLoad error " + ex.getMessage()); } if (this.debugOn) System.out.println("++PhotoEmployeeBMPBean_ejbLoad returning"); return; } /** * ejbPassivate */ public void ejbPassivate() { } /** * ejbRemove */ public void ejbRemove() throws javax.ejb.RemoveException { } /** * getEntityContext */ public javax.ejb.EntityContext getEntityContext() { return myEntityCtx; } /** * setEntityContext */ public void setEntityContext(javax.ejb.EntityContext ctx) { myEntityCtx = ctx; try { try { this.ds = itso.ibm.servlets.GetFromCtx.getDs(dsname); if (this.ds == null) System.out.println( "++PhotoEmployeeBMPBean_JNDIlookup datasource NULL"); else { System.out.println( "++PhotoEmployeeBMPBean_JNDIlookup datasource OK"); } } catch (Exception e) { System.out.println( "++PhotoEmployeeBMPBean_JNDIlookup datasource exception " + e.toString()); } } catch (Exception ex) { System.out.println( "++PhotoEmployeeBMPBean_setEntityContext " + ex.toString()); } } /** * unsetEntityContext */ public void unsetEntityContext() { myEntityCtx = null; } /**

286

DB2 for z/OS and WebSphere: The Perfect Couple

* ejbCreate */ public ejb.empl.PhotoEmployeeBMPKey ejbCreate() throws javax.ejb.CreateException { System.out.println("++PhotoEmployeeBMPBean_ejbCreate"); return null; } /** * ejbPostCreate */ public void ejbPostCreate() throws javax.ejb.CreateException { } /** * ejbFindByPrimaryKey */ public ejb.empl.PhotoEmployeeBMPKey ejbFindByPrimaryKey( ejb.empl.PhotoEmployeeBMPKey prikey) throws javax.ejb.FinderException { ejb.empl.PhotoEmployeeBMPKey pk = null; this.prikey = prikey; this.empno = prikey.empno; System.out.println( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey " + empno); //System.out.println("++PhotoEmployeeBMPBean_JNDIlookup connection OK"); java.sql.ResultSet rs = null; try { conn = ds.getConnection(); System.out.println( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey connection OK"); rs = selectByPrimaryKey(this.empno); if (rs != null) { if (!rs.next()) { if (this.debugOn) System.out.println( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey NO photo"); } else { rs.close(); pstmt.close(); pk = prikey; } } else { pstmt.close(); } conn.close(); } catch (java.sql.SQLException ex) { System.out.println( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey SQLException " + ex.toString()); throw new javax.ejb.EJBException( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey SQL error " + ex.getMessage()); } catch (Exception ex) { System.out.println( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey Exception " + ex.toString()); throw new javax.ejb.EJBException( "++PhotoEmployeeBMPBean_ejbFindByPrimaryKey error " + ex.getMessage()); } return pk;

Chapter 11. Sample application

287

} /** * ejbStore */ public void ejbStore() { System.out.println("++PhotoEmployeeBMPBean_ejbStore"); /*------------------------*/ if (!isModified) return; /*------------------------*/ ejb.empl.PhotoEmployeeBMPKey prikey = (ejb.empl.PhotoEmployeeBMPKey) myEntityCtx.getPrimaryKey(); String empno = prikey.empno; //String imagetype = prikey.photo_format; System.out.println( "++PhotoEmployeeBMPBean_ejbStore " + empno + " imagetype " + "N/A"); } private java.sql.ResultSet selectByPrimaryKey(String empno) throws java.sql.SQLException { java.sql.ResultSet rs = null; if (this.debugOn) System.out.println( "++PhotoEmployeeBMPBean_selectByPrimaryKey looking for photo for " + empno); pstmt = conn.prepareStatement(emplphotozos); pstmt.setString(1, empno); rs = pstmt.executeQuery(); if (this.debugOn) System.out.println( "++PhotoEmployeeBMPBean_selectByPrimaryKey returning resultset"); return rs; } public byte[] getImage() { //try { System.out.println("++PhotoEmployeeBMPBean_getImage"); return this.imagebytes; /* } catch (java.sql.SQLException ex) { System.err.println( "++PhotoEmployeeBean_getImage SQLException " + ex.toString()); return null; } */ } }

After the Java code has been completed, we still have some basic work to do.

Completing the deployment descriptor


The deployment descriptor ejb-jar.xml file has to be completed as before. We open de ejb-jar.xml file in its own specialized editor by double-clicking. Select the Beans tab at the bottom of the window, and highlight PhotoEmployeeBMP. The information to add is the binding information for JDBC. This information is indirect. It is a reference to a resource definition that is assumed to be available at execution time in the WAS V5 servers (containers) running this application. This name can be changed during deployment. We use the name jdbc/ITSO1.

288

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-52 displays the Beans panel inside the deployment descriptor of the BMP project. It shows the name of the BMP Bean that will be used for the lookup in the name space and the four classes that are part of the BMP.

Figure 11-52 Beans panel of the EJB Deployment Descriptor

We still miss a reference to the data source. To fix this, switch to the References tab of the deployment descriptor (Figure 11-53).

Figure 11-53 ITSODB2 to jdbc/ITSO1

Chapter 11. Sample application

289

In this panel we establish the link between the symbolic data source name ITSODB2 used in the Bean code, and the logical data source name jdbc/ITSO1. During deployment we still can adapt this value. In reality we introduced an additional indirection. We set the container authorization type to container, which means that when the connection to DB2 takes place, the user ID is implicitely picked up from the thread under which the connection takes place. This user ID could be the server (servant) user ID, or if a sync to thread took place, it is the U(ser)token that was put on the thread by the J2EE authorization mechanism. The authorization type is set in the deployment descriptor ejb-jar.xml for this Bean. Each EJB also has a lookup name (JNDIName) with which it can be found in the name space. We simplify this name by taking off the first ejb (see Figure 11-52 on page 289). We now save the deployment descriptor. The last operation that has to be done for this project is the generation of the deployment code. This is the same as before. Highlight the project, right-click, and select Generate Deployment and RMIC code.

11.2.5 Completing the model with the session Bean


So far we have constructed several entity Beans. However, the real entry to the model is a session Bean. With a WSAD wizard we generate an additional stateless session Bean ITSOAccessBean. All access to the entity Beans will transit through this session Bean. This is the entry point to the model. The advantage of using an intermediate session Bean instead of going directly to the entity Beans is that the transactional state can be controlled more easily when entering the session Bean method. Once the transactional state has been established when a method is entered, all methods in the entity Beans can continue to use this state. The Bean has four business methods, corresponding with the requested actions from the browser. Additional options passed through the java.util.HashMap object allow the session Bean method to select different entity Beans (CMP, BMP, with JDBC or SQLJ). As a reminder, all business methods that have been created in the ITSOAccessBean have to be promoted to the Local/Remote object. The session Bean is created in the ItsoEJB1 project. To create the session Bean, go to a J2EE perspective with the J2EE hierarchy view active (Figure 11-54), and highlight EJB Modules/ItsoEJB1/Session Bean. Right-click and select New Session Bean.

Figure 11-54 New session Bean

In the next window (Figure 11-55 on page 291), enter/select the name of the Enterprise project. We use ItsoEJB1.

290

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-55 New Enterprise Bean window

Click Next, and go to a window like Figure 11-56. Select the type, Session Bean. (Note that Session Bean was automatically selected.) Enter the Bean name, the Source folder, and the Java Default package of the Bean.

Figure 11-56 Create an Enterprise Bean

Click Next, and we go to the next screen with Bean options (Figure 11-57 on page 292).

Chapter 11. Sample application

291

Figure 11-57 Enterprise Bean details

Our session Bean will be stateless; it behaves basically like a transaction without state, and we request a local interface (but also have the remote interface checked, as it is indeed possible to have both). Click Finish. Figure 11-58 shows the layout view of the new Bean. A session Bean also has life-cycle methods, those starting with ejb. We added four get methods (business) corresponding with the request that will emerge from the actions.

Figure 11-58 Session Bean layout view

The four business methods are: getDepartment() getDepEmployeeList() 292


DB2 for z/OS and WebSphere: The Perfect Couple

getEmployee() getImage() Each method returns a data transfer Bean with requested information, if the request went fine; otherwise the return is null. We always have three input parameters, as can be seen in Example 11-13, for getEmployee(). ParameterS 1 and 3 are obvious; parameter 2, a HashMap, can be used for communication between components, for example, for error information.
Example 11-13 getEmployee() method public Employee getEmployee( String empno, java.util.HashMap reqhm, boolean debugOn) { .................. }

The resulting data transfer Bean will then be passed to the view component. This part of the scenario is shown in Figure 11-59.

M odel

C on troller
ITS OA c c ess SessionEJ B

Employ ee Entity /C MP

Action s

To view
Put data transfer in Servlet Container

d ata tran sfer b ean

g e tE mplo ye e () ge tImage () ge tD e partme nt() g e tD e pE mploye e List()

D epartment Entity /C MP

P hotoE mploy ee E ntity /B MP

S ervlet
T4

P hotoEmploy ee E ntity /C MP

T2
D B2

Action con trol

EJBs

Figure 11-59 Data transfer between controller and model

The deployment descriptor for the EJB project (ejb-jar.xml) contains specific parts for this Bean. Important information is the JNDIname of this Bean in its section. The convention is that this name should always start with ejb/. With this name, the Bean will be known in the name space, which, as we recall for WAS V5, is located in the HFS. The lookup of the Bean home via a direct name, or indirectly via a reference, will be for this name. Figure 11-60 on page 294 shows the Bean tab for the session Bean (ITSOAccess) of the deployment descriptor.

Chapter 11. Sample application

293

Figure 11-60 Deployment Descriptor Bean section for ITSOAccess

From within the session Bean ITSOAccessBean, the business methods will access the entity Beans. To look up the homes of those Beans, which is the first step in the access, we use reference names. Those names have to be connected to the real JNDI home names. This information is in the References section of the deployment descriptor, as shown in Figure 11-61 on page 295.

294

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-61 References in deployment descriptor to entity Beans

As an example let us have a quick look at the code to invoke the getEmployee() method on the CMP Bean ITSOEmpBean, shown in Example 11-14.
Example 11-14 getEmployee method public Employee getEmployee( String empno, java.util.HashMap reqhm, boolean debugOn) { empl.Employee employee = null; String ejbref = "ITSOEmp"; System.out.println( "++ITSOAccessBean_getEmployee looking_up " + ejbref + " for key " + empno); ITSOEmpLocal infoemployee = null; ITSOEmpKey infoprimarykey = new ITSOEmpKey(empno); /* fill primary ky */ infoemployee = (ITSOEmpLocal) itso.ejb.util.EjbFactory.singleton().findByRefPrimaryKey( ejbref, ITSOEmpLocal.class, infoprimarykey); if (infoemployee == null) { String infomsg = ++ITSOAccessBean_getEmployee Employee " + empno "NOT found"; doErr(infomsg, reqhm); return null; } else { if (debugOn) System.out.println( ++ITSOAccessBean_getEmployee handle to employee OK"); return infoemployee.getEmployee(); }

Chapter 11. Sample application

295

The steps are following: As parameters we get the empno and an HashMap for communication. The empno is used to set the primary key class. We use a utility class Ejbfactory, which: Does lookup of the home of the entity CMP via a reference Executes immediately a finder by primary key Returns the local object On the local object, we execute getEmployee() to get the data transfer Bean Employee. We return the data Bean to controller or null if unsuccessful, and error information is returned via the HashMap. The final preparation step for the session Bean is the generation of the deployment code. Highlight the ItsoEJB1 project, right-click, and select Generate Deployment and RMIC code. This takes you to a window like Figure 11-62.

Figure 11-62 Select Beans to generate deployment code

Select the Beans for which you want to generate deployment code. Click Finish. After this, the Model component of our scenario is complete.

11.3 The View component of the MVC model


In a MVC design, the view component is responsible for the presentation of the results. The recommendation is to use JavaServer Pages (JSPs) for the viewing component. That is what we also do in our scenario with one exception, the presentation of the picture. JSP does not support the presentation of images, so we have to introduce one additional servlet SVImage to do this work. Figure 11-63 on page 297 shows the four JSPs and the servlet SVimage, on the left side. The selection of the correct view component occurs under the guidance of the Controller. The view component is part of a Web project. In our case, Controller and View are located in the same Web project, ItsoWeb1.

296

DB2 for z/OS and WebSphere: The Perfect Couple

Browser

View
Model

Controller
EmpIndexJSP
ITSOAccess SessionEJB

Employee Entity/CMP

Actions
EmployeeJSP SVImage

Data Transfer Bean

data transfer bean

getEmployee() getImage() getDepartment() getDepEmployeeList()

Department Entity/CMP

Put data transfer in Servlet Container

PhotoEmployee Entity/BMP

DepartmentJSP

Servlet
EJBs

PhotoEmployee Entity/CMP

T4
DB2

T2

DepEmployeeListJSP

JSPs

Action control

Figure 11-63 Views for MVC

As mentioned above, the view component consists of four JSPs and one presentation servlet. Before the controller dispatches the presentation to the JSPs, the data transfer Bean, which was returned from the session Bean in the model, has been put in the main servlet container. This happens in the actions in the controller with the following instruction:
request.setAttribute("infoemployee", employee);

The same instructions can be found for the other data transfer Beans. As a result, it is possible to use JSP tags for picking up the contents of the data transfer Beans. This is a common technique. To illustrate this, we use the JSP ITSOEmployee.jsp, shown in Example 11-15. jsp:useBean addresses a Bean of type empl.Employee located in the request container with label infoemployee. jsp:getProperty references infoemployee and pulls out the property, for example, empno. A getEmpno() is executed on the Bean. The code for all JSPs can be found in the additional material that is downloadable from the Web. See Appendix A, Additional material on page 319, for details.
Example 11-15 ITSOEmployee.jsp <BODY bgcolor="#ffff80" text="#0000ff" link="#00cc00"> <jsp:useBean id="infoemployee" class="empl.Employee" scope="request"/> <P><IMG src="goldengate.jpg" width="512" height="91" border="0"><BR> <BR> <FONT size="+3">Employee Information for <jsp:getProperty name="infoemployee" property="empno"/></FONT></P> <HR> Chapter 11. Sample application

297

<TABLE border="1"> <TBODY> <TR> <TD>empno</TD> <TD width="200"><jsp:getProperty name="infoemployee" property="empno"/></TD> <TD rowspan="8" width="152"><IMG src="/ItsoEmpl/employeeEJB.do?action=image&TRACE=YES&empno=<jsp:getProperty name="infoemployee" property="empno"/>&photobean=<jsp:getProperty name="infoemployee" property="photobean"/>" border="0"></TD> </TR> <TR> <TD>firstname</TD> <TD><jsp:getProperty name="infoemployee" property="firstnme"/></TD> </TR> <TR> <TD>lastname</TD> <TD><jsp:getProperty name="infoemployee" property="lastname"/></TD> </TR> ............ </TBODY> </TABLE> <hr> <TABLE width=100%> <TR> <TD width=50%> <A HREF=/ItsoEmpl/empIndex.do>BACK TO HOME PAGE</A> </TD> <TR> </TABLE> </BODY> </HTML>

The explanation of the view component here is only for completeness. For further reading about JSP techniques, it is best to consult more specialized documentation on this subject.

11.4 Controller component of MVC


In the J2EE Web environment, all requests coming from the Browser are handled in a servlet. In the MVC design this servlet, together with other non-business classes, should act as a navigator and controller. No specific business work should be done in the servlet, but, depending on a token in the input from the browser, work should be dispatched to models. The only role of the servlet is to dispatch to actions, which are the links to the models, or to activate the presentation components. We decided to use the Struts framework, which imposes the usage of the MVC convention. Struts is an open source framework for building Web applications using the model-view-controller (MVC) architecture. Most common Web applications can find some benefit in using Struts. As we have seen earlier, the MVC pattern allows us to design the model (business logic) of the application in a traditional fashion. Adding a Web controller and view transforms this model into a Web application. Struts helps build the controller and view parts, thus allowing you to focus on the business logic. This is shown in Figure 11-64 on page 299.

298

DB2 for z/OS and WebSphere: The Perfect Couple

Browser

Model

View ?

Controller
ITSOAccess SessionE JB

E mployee E ntity/CMP

action form action form action form action


getEm ployee() getIm age() getDepartm ent() getDepEm ployeeList()

Department Entity/CMP

PhotoEmployee Entity/BMP

PhotoE mployee Entity/CMP

JSP's

T4 EJBs
DB2

T2

ActionServlet

StrutsConfig XML

Figure 11-64 Controller

The controller is built in a Web project ItsoWEB1. During the creation of the project we ask the inclusion of Struts support. Now we go over the sequence of actions to create the Web project. Create a new project (top left button in WSAD), and in the selection panel, select Web in the left column, and Dynamic Web Project on the right side of the window shown in Figure 11-65.

Figure 11-65 Select Web/Dynamic Web Project

Chapter 11. Sample application

299

Click Next. In the next screen (Figure 11-66) give a name to the project (ItsoWEB1).

Figure 11-66 Project Name

Click Next. The next window looks like Figure 11-67.

ItsoEmpl

Figure 11-67 J2EE level and application

This project is at J2EE level 1.3, and is also part of the Enterprise Application Itso1EAR, the same Application Project as the EJBs. An important element to specify here is the context root, which is the first part the URL requests for this Web application; for example, the original URL request would be like:
http://wtsc54.itso.ibm.com:9080/ItsoEmpl/empIndex.do

300

DB2 for z/OS and WebSphere: The Perfect Couple

Click Next and a window for special support choices is displayed (Figure 11-68).

Figure 11-68 Including Struts support and some JSP tags

Check Add Struts support, and the struts.jar, JSP TLD files, belonging to the Struts framework will be included in the project. As a result the Struts framework will be automatically part of this Web project. This includes a Servlet called ActionServlet, and TLD files (Customer tag files for JSP). Click Next. The window in Figure 11-69 is shown next.

Figure 11-69 Struts level 1.1

The deployment descriptor of the Web project will automatically indicate the presence of Struts. Struts exist in different versions. We select level 1.1. Accept the defaults, and click Finish. The project is now created. The heart of the struts framework is the Actionservlet, which is part of the included modules. All input is received by this servlet. Depending on a token in the URL request and mapping

Chapter 11. Sample application

301

information in the struts-config.xml file, the Actionservlet dispatches an action, as shown in Figure 11-70.

JS P
s e r v le t

A c tio n S e r v le t

a c t io n s A c t io n s

s tr u ts - c o n f ig . x m l

a c tio n s F o rm s

Figure 11-70 Struts operation principle

In general, an action is associated with a form. The form allows an easy retrieve and a verification of the input before the action is really linking to the model. A look at the struts-config.xml file can help to clarify things. This file is located under the Webcontent (document root) of the Web project. In a J2EE perspective, looking at the Project Navigator in the J2EE view, we observe the structure of the Webcontent for the project (ItsoWEB1). Note the location of the JSPs in there, and under the subdirectory WEB-INF, the deployment descriptor web-xml, struts tld files, and struts-config.xml (Figure 11-71 on page 303).

302

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-71 Webcontent directory structure

Double-click the struts-config.xml to open it, and select the Action Mappings tab. Your screen should look like Figure 11-72.

Figure 11-72 Mapping in Struts

In the left part of Figure 11-72 we recognize the action token and in the right part the corresponding action module class. In the Form Bean Specification section, you can specify a form class if one is associated with this action. The action classes will invoke the model, while

Chapter 11. Sample application

303

the form class allows easy access to the input from the browser. The token mapping comes from the URL. For example, in the following URL:
http://wtsc54.itso.ibm.com:9080/ItsoEmpl/employeeEJB.do

ItsoEmpl is the context root as specified in the Application.xml of the EAR project. employeeEJB.do is composed of two parts:

*.do triggers the ActionServlet (URL specification in the deployment descriptor). employeeEJB is used for the mapping to the action.
Four tokens have been defined. All have an action and a form associated, except empIndex, which only drives the menu JSP. To understand how the *.do part leads us to the Actionservlet, we have a look in the file web.xml in the directory Webcontent/WEB-INF. We open the file by double-clicking. This opens the Servlets and JSPs window (Figure 11-73). On the left side in the window, we see the names of the Servlets, which are part of the Web project. Put the focus on action. On the right side, we see the name of the java class that corresponds with this Servlet; and under URL Mappings, the url *.do that leads to it. The other two Servlets are specialized; for example, the SVimage is required for sending images to the browser. JSP supports only text. This Servlet also has a URL mapping, which will be used from within the controller as a new forward action. The information on the action servlet was created automatically when we included Struts support with the Web project. .

Figure 11-73 Actionservlet in the Web project

The action Servlet forwards to actions, or to the View component. The actions in our case will direct the request to the models. The entry to the models is a session Bean, as mentioned before. Example 11-16 on page 305 shows the code for an action for the URL employee.do.

304

DB2 for z/OS and WebSphere: The Perfect Couple

Example 11-16 Action class for employee.do package itsoweb1.actions; import ....... import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import empl.Employee; import empl.AcquireEmpModel; public class EmployeeEJBAction extends Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); EmployeeEJBForm employeeEJBForm = (EmployeeEJBForm) form; String action = employeeEJBForm.getAction(); String fw = "info"; boolean debugOn = true; try { String empno = employeeEJBForm.getEmpno(); HashMap reqhm = new HashMap(); if (action.equals("info")) { /* What type of Bean will be used for Employee? */ reqhm.put( "empaccess", employeeEJBForm.getEmpaccess()); /* lookup Local Home of Session bean, invoke getEmployee through Object interface */ Employee employee = (AcquireEmpModel.acquireLocal(debugOn)).getEmployee(empno, reqhm, debugOn); if (employee != null) { employee.setPhotobean(employeeEJBForm.getPhotobean()); request.setAttribute("infoemployee", employee); /* pass employee via request container */ } else { ........ request.setAttribute("ERRORMSG", errormsg); /* pass ERRORMSG via request container */ fw = "empIndex"; /* forward is index menu */ } forward = mapping.findForward(fw); /* set forward */ } else { /* What type of Bean will be used for Image? */ reqhm.put("photobean",employeeEJBForm.getPhotobean()); /* lookup Local Home of Session bean, invoke getEmployee through Object interface */ byte[] image = (AcquireEmpModel.acquireLocal(debugOn)).getImage(empno, reqhm, debugOn); if (image != null) { request.setAttribute("IMAGE", image); /* pass image via request container */ fw = "image"; /* forward is image */ forward = mapping.findForward(fw); /* set forward */ } else { System.out.println("++ImageOut_write NO image"); } } } catch (Exception e) { ............ request.setAttribute("ERRORMSG", errormsg); fw = "empIndex"; } } forward = mapping.findForward(fw); Chapter 11. Sample application

305

return (forward); } }

A user action class is an extension of the Action class of the Struts framework. The important method to consider and to write is perform. This method has an imposed signature and must return a forward class. This class will be used by the Action servlet to determine what to do next. The parameters passed on the call allows access to all required information, including the request. In our example we process two demands: Text information about the employee Image of the employee In both sections, after recuperating the params, the session Bean, entry to the model, is instantiated via a local home interface, and a business method is invoked through the returned local object. The response object is then stored in the container of the request as an attribute, which can be easily used by the view (JSP).

11.5 The enterprise J2EE application


All EJB projects and the ItsoWEB1 project are part of the same Enterprise Application Itso1EAR. In the EJB projects we have defined a JDBC reference to our Data Source. The name jdbc/ITSO1 is certainly not the name of the real defined data source in the container. This linkage, however, can be corrected at deployment time. In the EAR project we can have a look at the application descriptor file, Application.xml. Open this file by double-clicking. It also has a specialized editor. In the window that opens, select the Module tab from the bottom menu (Figure 11-74).

Figure 11-74 Modules in application ItsoEAR1

On the left side, we have the list of all Web and EJB projects included in the EAR project, and under Project Utility JARs, a list of additional jars with support/utility classes. The Web project ItsoWeb1 is highlighted, and as a result on the right we find the value of the Context Root,

306

DB2 for z/OS and WebSphere: The Perfect Couple

which has to be included as the first token in the URL requests. After the context root, the

action has to be specified; for example:


http://wtsc54.itso.ibm.com:9080/ItsoEmpl/EmplIndex.do

Where:

ItsoEmpl: Context root (selects the WebApplication) EmplIndex.do EmplIndex: Will be the action that is defined by the Struts config file .do: Is the URL matching that points to the Actionservlet
The .ear file can be exported directly from the WSAD development tool and used as input in the deployment process into WAS V5 for z/OS. To do so, highlight the project Itso1EAR, right-click, and select Export. In the Export panel, select the EAR file, click Next, and follow the instructions for selecting a name and a directory. At this stage it is not required to include the source files. We call our file Itso1EAR.ear.

11.6 Deployment of the EAR file


Before we can deploy and start an application on WAS V5 for z/OS, we must be sure that all required resources have been correctly defined in advance. The scenario that we developed uses only DB2 as a resource (but could use it through several data sources). The temporary name we gave to this data source is jdbc/ITSO1. This resource does not exist for the Application Server in which we want to have the EAR file deployed. We will link the temporary name to an available resource during the deployment. Also, when the data source name is missing, we have the opportunity to fill in the right one. On the WAS Admin console master menu, select Enterprise Applications from the left menu (Figure 11-75).

Figure 11-75 Installing a new application

Chapter 11. Sample application

307

As our EAR file is located on the workstation, so we use the Local path option, and specify the path name of the file. Click Next and accept the default binding and mappings, as shown in Figure 11-76.

Figure 11-76 Accept the default

Click Next and you will see an option list (Figure 11-77).

Figure 11-77 installation options

Use the options as indicated above. It is possible (if needed) to regenerate the deployment code for the EJBs, but this is not required in our case. Click Next. Figure 11-78 on page 309 is next. It lists the projects that are part of this J2EE Application.

308

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-78 Overview of the projects part of the J2EE application

Click Next. This takes you to Figure 11-79, a list of all the EJBs that are part of this J2EE application and their JNDIName, which can be changed if needed. We do not recommend this. Try to use the correct names in WSAD.

Figure 11-79 JNDI names for the EJBs

In our case there is no need to change the JNDInames, and we accept by clicking Next. A new window, Figure 11-80 on page 310, shows the datasource references as set in WSAD.

Chapter 11. Sample application

309

Figure 11-80 Specifying the real datasource name

The right datasource name, which has been defined as a JDBC resource in WAS V5, has to be set here for default datasources. This can be a data source using T2 or T4 connectivity, as long as we can reach our DB2 tables through it. Simply override the values with the correct jdbc/ name. Click Next. The window in Figure 11-81 shows up next.

Figure 11-81 jdbc Data Source references

Again datasource JNDI names have to be overridden with real existing values. Resource authorization can also be changed. Click Next. Figure 11-82 on page 311, which is next, displays the references between the artifacts in the J2EE application.

310

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-82 References to EJBs

What is shown here is the result of references from the Web application or the session EJB to the Beans. The proposed values are a result of information in the deployment descriptors. We can accept those values, and click Next. A new window, related to the PhotoBMP, pops up (Figure 11-83).

Figure 11-83 BMP reference

Change again to the right data source, and click Next. The next panel (Figure 11-84 on page 312) is related to the Virtual Host, on which this application can be reached.

Chapter 11. Sample application

311

Figure 11-84 Virtual host

This information is only related with the Web application. A J2EE Web server has the concept of Virtual Host being a distinct DNS address for a server. It also has a default_host associated. Our current Webapp in the EAR file is linked to the default Virtual Host. Click Next once more. This takes use to Figure 11-85, a final overview of all modules in this J2EE application, and gives you the possibility to indicate in which Application Server this J2EE application must be deployed.

Figure 11-85 Application server selection

Normally we would have a choice between several servers installed on WAS V5. However, in our case, only one is available. Accept and click Next. This takes us to Figure 11-86.

Figure 11-86 Check protection

We do not consider protection settings in our application, and we click Next. A last summary overview is displayed (Figure 11-87 on page 313).

312

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-87 Summary

Click Finish. The application is now installed. When done, Figure 11-88 is displayed. The application was successfully installed, and you can now save to the master configuration.

Figure 11-88 Install confirmation

11.7 Test of the application


To make sure everything is working fine, we do a quick test of the application. To start, we enter the URL for the index in our Web browser:
http://wtsc54.itso.ibm.com:9080/ItsoEmpl/empIndex.do

Chapter 11. Sample application

313

The index screen is displayed as shown in Figure 11-89.

000140

Figure 11-89 EmpIndex

In this window we have three sections: Employee Department EmployeeList in Department For the selected option, we have to enter the key, and select the type of application we want to use (if available). For instance, when retrieving an Employee, we can indicate which type of entity Bean should be used for the Employee data and the Employee picture. We specify an empno, 000140, and keep CMP/JDBC for both Emp and Photo. The result is shown in Figure 11-90 on page 315.

314

DB2 for z/OS and WebSphere: The Perfect Couple

Figure 11-90 Employee and picture retrieved

Chapter 11. Sample application

315

316

DB2 for z/OS and WebSphere: The Perfect Couple

Appendixes

Copyright IBM Corp. 2005. All rights reserved.

317

318

DB2 for z/OS and WebSphere: The Perfect Couple

Appendix A.

Additional material
This redbook refers to additional material that can be downloaded from the Internet as described below.

Locating the Web material


The Web material associated with this redbook is available in softcopy on the Internet from the IBM Redbooks Web server. Point your Web browser to:
ftp://www.redbooks.ibm.com/redbooks/SG246319

Alternatively, you can go to the IBM Redbooks Web site at:


ibm.com/redbooks

Select the Additional materials and open the directory that corresponds with the redbook form number, SG24-6319.

Using the Web material


The additional Web material that accompanies this redbook includes the following file: File name SG246319.zip Description Sample application used throughout the book

How to use the Web material


Create a subdirectory (folder) on your workstation, and unzip the contents of the Web material zip file into this folder. The zip file contains the following files: File name itso1EAR.ear Description EAR file containing the sample application 319

Copyright IBM Corp. 2005. All rights reserved.

JCL used to create DB2 objects (DSNTEJ1).txt JCL used to create DB2 LOB objects (DSNTEJ7).txt

Job to create the DB2 objects Job to create the LOBs

320

DB2 for z/OS and WebSphere: The Perfect Couple

Related publications
The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook.

IBM Redbooks
For information on ordering these publications, see How to get IBM Redbooks on page 322. Note that some of the documents referenced here may be available in softcopy only. DB2 for z/OS Version 8 Everything you ever wanted to know, ... and more, SG24-6079 Squeezing the Most Out of Dynamic SQL with DB2 for z/OS and OS/390, SG24-6418 DB2 for z/OS and OS/390: Ready for Java, SG24-6435 IBM WebSphere Application Server V5.0 System Management and Configuration, SG24-6195 EJB 2.0 Development with WebSphere Studio Application Developer, SG24-6819 WebSphere Studio Application Developer Version 5 Programming Guide, SG24-6957 Distributed Functions of DB2 for z/OS and OS/390, SG24-6952

Other publications
These publications are also relevant as further information sources: DB2 Universal Database for z/OS Version 8 Administration Guide, SC18-7413 DB2 Universal Database for z/OS Version 8 SQL Reference, SC18-7426 DB2 Universal Database for z/OS Version 8 Command Reference, SC18-7416 DB2 Universal Database for z/OS Version 8 Application Programming and SQL Guide, SC18-7415 DB2 Universal Database for z/OS Version 8 Utility Guide and Reference, SC18-7427 DB2 Universal Database for z/OS Version 8 ODBC Guide and Reference, SC18-7423 DB2 Universal Database for z/OS Version 8 Application Programming Guide and Reference FOR JAVATM , SC18-7414 DB2 Universal Database for z/OS Version 8 Installation Guide, GC18-7418 WebSphere Application Server for z/OS V5.0.2 Performance Tuning and Monitoring, SA22-7962 WebSphere Studio Application Monitor Installation and Customizing Guide, SC31-6312 DB2 Universal Database for z/OS Version 7 Application Programming Guide and Reference FOR JAVA, SC26-9932-05 or later

Copyright IBM Corp. 2005. All rights reserved.

321

Online resources
These Web sites and URLs are also relevant as further information sources: DB2 Universal Database for Linux, UNIX, and Windows Web site:
http://www.ibm.com/software/data/db2/udb/

DB2 Connect Web site:


http://www.ibm.com/software/data/db2/db2connect/

ISO Standards Web site:


http://www.iso.org

ANSI Standards Web site:


http://www.ansi.org

JDBC Specifications Web site:


http://java.sun.com/products/jdbc/

WebSphere Information Center Web site:


http://publib.boulder.ibm.com/infocenter/wasinfo/index.jsp

Using DB2 for z/OS in WebSphere for z/OS Version 5, Techdoc TD101072:
http://www-03.ibm.com/support/techdocs/atsmastr.nsf/WebIndex/TD101072

Setting client information strings in WAS: Technical support document number 1142347:
http://www.ibm.com/software/webservers/appserv/was/support/

Latest information on the complete DB2 UDB family:


http://www.ibm.com/software/data/db2/

How to get IBM Redbooks


You can search for, view, or download Redbooks, Redpapers, Hints and Tips, draft publications and Additional materials, as well as order hardcopy Redbooks or CD-ROMs, at this Web site:
ibm.com/redbooks

Help from IBM


IBM Support and downloads
ibm.com/support

IBM Global Services


ibm.com/services

322

DB2 for z/OS and WebSphere: The Perfect Couple

Index
Symbols
${DB2UNIVERSAL_JDBC_DRIVER_NATIVEPATH} 56 ${DB2UNIVERSAL_JDBC_DRIVER_PATH} 56 ${UNIVERSAL_JDBC_DRIVER_PATH} 56 *.do 304 .EAR file 38 .JAR file 38 .profile 26 .ser file 146, 171, 183 .so file 53 .sqlj extension 159 .WAR file 39 ? Parameter marker 114 PQ90211 22 PQ95284 23 PQ95881 30 Application Assembler 36 Application Component Provider 36 Application exceptions 157 Assembly descriptor 196 Assignment statement 144 Auditing 128, 136 Authentication 128 Authorization 128 Control 111 Type 290 -automaticbind NO 148 Auxiliary table 10

Numerics
1 Phase commit 79 1PC 80 2 phase commit 7980 4 tier programming model 37 4.x level data sources 80 64-bit mode 234 9672 G5 222

B
Base Application Server Node 41 BaseNode 51 Bean Managed Persistence 98, 151, 280 Bean Managed Transactions 194 Bind 118 Bind options DYNAMICRULES 120 ISOLATION 121 OWNER 120 QUALIFIER 120 BIND PACKAGE 18 BIND PLAN 18 BINDOPTIONS 276 BLOB 247, 249 BMP 100, 106, 151, 280 BMP vs. CMP 151 BMP with JDBC example 280 BMT 194 BN 51 Bottom-up approach 183, 249 Bottom-up mapping 259 Business integration 48

A
Abstract persistence schema 185 Access intent 218219 Access path 230 Accessors 263 Action token 303 Actionservlet 301, 304 activate() 96 Add SQLJ Support 274 Add Struts support 301 Additional Properties JVM 67 Administrative console 42, 45, 54, 307 Affinity routing 97, 99 Aged Timeout 225226 American National Standards Institute 15 ANSI 15, 20 ANSI X3.135-1999 15 Ant script 171, 275 APAR OW54622 233 PQ36011 22 PQ62695 29 PQ72453 29 PQ78165 29 PQ80079 24, 52 PQ80841 23, 26, 52 PQ83561 29 PQ90208 22 PQ90210 22

C
CACHEDYN 229 CAF 7 Call attachment facility 7 Call back methods 98 CallableStatement interface 115 CallableStatements 228 Callback methods 283 Call-level interface 140 CAST construct 146 Catalog database 9 CDB 202 Cell 51 Cell scope 81

Copyright IBM Corp. 2005. All rights reserved.

323

CF 205 CGI 90 Checkbox SQLJ exploitation 100 Checked exception 157 CICS 38, 246 CICS attachment facility 6 Claim processing 206 ClassName_SJProfile0.ser 140 CLASSPATH 27, 113, 235 CLEAR_TEXT_PASSWORD_SECURITY 129 Client application modules 38 ClientAccountingInformation 137 ClientProgramName 136 ClientUser 136 ClientWorkstation 136 CLOB 247, 249 close() 115 CLUSTER 12 Clustering indexes 12 CMP 100, 107, 151, 229, 247 CMP 2.0 266 CMP generated SQL 218 CMP mapping 183 CMR 266 CMR fields 272 CMT 156, 194 Collection of objects 263 Collections 19 com.ibm.db2.jcc.* 112 com.ibm.db2.jcc.DB2BaseDataSource 125 com.ibm.db2.jcc.DB2ConnectionPoolDataSource 113, 125 com.ibm.db2.jcc.DB2DataSource 113, 125 com.ibm.db2.jcc.DB2Driver 26 com.ibm.db2.jcc.DB2SimpleDataSource 113 com.ibm.db2.jcc.DB2XADataSource 113 com.ibm.jcc.DB2RowID 33 com.ibm.websphere.rsadapter.WSCallHelper 137 Commit 194 commit() 195 Common Gateway Interface 90 Communication Database 202 Comparing SQLJ and JDBC 110 -compile=false 140 Component-managed Authentication Alias 135 CONDBAT 229 Configuring type 2 connectivity 53 Connection context 143144, 179 Connection definition 250 Connection pool maintenance 224 Connection pooling 140, 222 Best practices 228 Connection Pools option 227 Connection Timeout 226 Connections 140 Connections and transactions 144 ConnectionWaitTimeoutException 225226 Consistency token 147 Constructor 143 Container 279

Container managed persistence 93, 100, 151, 229 Container managed relation 266 Container Managed Transactions 156, 173, 194 Context 143 Context root 300, 306 Context switch 103 Controller 246 Controller component 298 Controller region 40, 233 Coprocessor 14 Coupling Facility 205 CREATE INDEX 12 CreateException 183 CREATEIN 19 Creating a new Application Server 73 Credentials 128 CRUD methods 272 CS 146, 187, 212, 220 CTHEAD 229 CURRENT PACKAGE PATH 124 CURRENT PACKAGESET 123124 CURRENT SCHEMA 122 CURRENT SQLID 121 CURRENTDATA 216 Cursor stability 146, 187, 212 Cursor update 216 Custom Properties 61, 121, 123 Customer tag files 301 Customizable Performance Monitoring Infrastructure 222 Customize the serialized profile 118119 Customized SQLJ 111 CVS 161

D
Daemon 75 Data access component 105 Data Control Language 14 Data Definition Language 14 Data integrity 2 Data Manipulation Language 14 Data perspective 249, 273 Data sharing considerations 216 Data Source 51, 57 Properties 58 Under the JDBC provider 53 Data structures 8 Data transfer Beans 264 Data transfer object 152 Database languages Standards 15 Database management system 2 Database request module 17 Database services address space 5 Databases 9 Data-partitioned secondary index 13 DataSource interface 22, 32, 113, 125, 140141 Datasource settings for authentication 134 DataSource versus datasource 141 DB Connect

324

DB2 for z/OS and WebSphere: The Perfect Couple

Enterprise Edition 3 DB2 attachment facilities 6 DB2 bind options for Java applications 120 DB2 Connect 3 Application Server Edition 3 Personal Edition 3 Unlimited Edition 3 DB2 dynamic statement cache 229 DB2 federated database technology 10 DB2 Interactive 6 DB2 JDBC Legacy Type 2 driver 22 DB2 JDBC Legacy type 2 driver 22 DB2 locking 210 DB2 package 147 DB2 Performance Expert 230 DB2 precompiler 14 DB2 resource manager 204 DB2 Server for VSE & VM 4 DB2 transaction manager 202 DB2 UDB Enterprise Server Edition 3 Express Edition CPU Option 3 Personal Developers Edition 3 Personal Edition 3 Universal Developers Edition 3 Workgroup Server Edition 3 Workgroup Server Unlimited Edition 3 DB2 UDB for iSeries 4 DB2 UDB for z/OS and OS/390 Components 4 DB2 Universal Database Family 2 DB2 Universal Driver 21 DB2 Universal JDBC Driver Provider 51 DB2 Universal JDBC Driver Provider (XA) 51 db2.jcc.propertiesFile 68 DB2BaseDataSource 236 DB2Binder utility 29 DB2Connection 33 DB2Diagnosable 33 DB2-established stored procedure 5 db2jcc.jar 2627, 164 db2jcc_javax.jar 27 db2jcc_license_cisuz.jar 27, 164 db2jcc_license_cu.jar 164 db2profc 118, 147 DB2RowID 33 DB2Sqlca 33 db2sqljbind 32, 120, 148 db2sqljcustomize 32, 112, 119120, 147148, 213, 276 db2sqljprint 188 DB2T4XAIndoubtUtil 205 DB2T4XAIndoubtUtil utility 30 DB2UNIVERSAL_JDBC_DRIVER_PATH 83 DBRM 17, 118, 123 DDF 5, 22 Declarative query language 13 Default context 144 Default database 9 Deployer 37 Deployment and RMIC code 274, 290, 296

Deployment code 270 Deployment descriptor 51, 93, 132, 194, 265, 269, 279, 288, 293 Deployment of the EAR file 307 DESCRIBE 28 DESCRIBE SQLDA 28 DESCSTAT 2829, 116 Detailed application flow 153 DFSLI000 6 -DISPLAY DDF 30 -DISPLAY THREAD 136 Distributed data facility 129 Distributed data facility services address space 5 Distributed Relational Database Architecture 20 Distributed transaction support 24 DISTSERV 18, 112, 124 DLLs 27, 53 DNS address 312 Does Not Exist 224 DPSI 13 Drain processing 206 DRDA 18, 22, 204 DriverManager 125 DriverManager interface 22, 140 DriverManager.getConnection 125 DSN command processor 6 DSNALI 7 DSNCLI 6 DSNDB04 9 DSNDB06 9 DSNDB07 9 DSNELI 6 DSNHDECP 202 DSNL004I 30 DSNRLI 7 DSNTIJMS 29 DSNTIP4 29 DSNTIPE 229 DSNZPARM 9, 28 CACHEDYN 229 CONDBAT 229 CTHEAD 229 DESCSTAT 28 EDMDSMAX 230 EDMDSPAC 230 EDMSTMTC 230 MAXDBAT 229 TCPALVER 130 DTO 152153 Dynamic Application Environment 233 Dynamic SQL 14, 146 Statement caching 14 Dynamic statement caching 14 Dynamic Web Project 299 DYNAMICRULES(BIND) 120 DYNAMICRULES(RUN) 120

E
E.F. Codd 2 EA 254 Index

325

EAR 3738, 254 EAR file deployment 307 File 272 EAR project 306 EDMDSMAX 230 EDMDSPAC 230 EDMPOOL 230 EDMSTMTC 230 EJB 92 Summary 105 EJB 2.0 specification 247 EJB container 38 EJB module Enabling SQLJ support 184 EJB project 160, 253 EJB QL 185 EJB Query Language 185, 268 EJB to RDB mapping 260 EJBContext.getUserTransaction() 195 ejbCreate 183 EJBException 157, 182 Ejbfactory 296 ejb-jar.xml 279, 282, 288, 293 EJBQL 268, 272 ENCRYPTED _USER_AND _DATA_SECURITY 130 ENCRYPTED_PASSWORD_SECURITY 129 ENCRYPTED_USER_AND_PASSWORD_SECURITY 130 ENCRYPTED_USER_PASSWORD_AND _DATA 130 Enterprise achive 254 Enterprise Application 254 Enterprise application archive 3738 Enterprise Information System 38 Enterprise JavaBean 205 Enterprise JavaBeans 92 EntirePool 226 Entity Bean 106, 151 Entity Bean isolation level 218 Entity Beans 38, 98 Bean-Managed Persistence 98 Container-Managed Persistence 100 ENV parameter 70 Environment entries 71 Environment variables 26 CLASSPATH 27 LIBPATH 27 PATH 26 ESAME mode 234 Exception handling for EJBs 154 Exceptions 157 Exclusive lock 211 Executable statement 144 EXECUTE authority 112 executeQuery() 114 executeUpdate() 115 Execution context 158 ExecutionContext 159 EXPLAIN 230 export statement 27

F
FailingConnectionOnly 226 Federated capabilities 2 Finder 272 Finders 263 First contact subsystem 202 FixPak 5 22 FMID 23 FOR READ ONLY 216 FOR UPDATE 216 Forced data access abstraction 99 Foreign key 16, 248 Forward engineering 183 Function Module Identifier 23

G
Gateway subsystem 203 GENERATE_UNIQUE function 215 GENERATED ALWAYS 216 getBytes 33 getConnection 141 getConnection().setAutoCommit() 143 getDB2CurrentPackagePath 33 getDB2CurrentPackageSet 33 getJccLogWriter 33 getMessage 33 getSqlca 33 getSqlCode 33 getSqlState 33 getStatus() 195 Getters 272 getWarnings 159 Global security 135 Global transaction 192, 205 Global transaction support 205 Global unit of work 88 GUOW 88

H
Hardware configuration 222 HashMap 296 HDDA210 24 Heapsize 234 HTTP 104 HTTP clients 38 HTTP server 40

I
IBM DB2 Legacy Driver 21 IBM extensions 282 IEEE floating point 222 IFI 7 Imported tables 253 IMS 38, 246 IMS attachment facility 6 In Free Pool 224 In Use 224 Indexes 11

326

DB2 for z/OS and WebSphere: The Perfect Couple

Indoubt 193 Indoubt transaction resolution 208 Industry standards 15 Initial Heap Size 235 INITIAL_CONTEXT_FACTORY 142 InitialContext 141 Instrumentation facility interface 7 Integrated Cryptographic Service Facility 222 Intent exclusive lock 211 Intent share lock 211 Internal resource lock manager 5 International Organization for Standardization 15 IRLM 5, 234 IS-lock 211 ISO 15, 20 ISOLATION 121 ISOLATION bind option 213 Isolation levels 187, 212 Iterator conversion statement 146 Iterator declaration 144 IVP tables 246 IX-lock 211

J
J2EE 19, 24, 3536 J2EE benefits 39 J2EE container 92 J2EE data access architecture 90 J2EE JTA/XA transaction 80 J2EE perspective 255256, 273 J2EE project 160 J2EE roles 36 JAAS security entries 163 Java 2 Enterprise Edition 19, 3536, 92 Java architecture guide 89 Java archive 38 Java Common Connectivity 22 Java Data Objects 104 Java Database Connectivity 19 Java identifiers 114 Java Interface Definition Language 40 Java Message Service 40 Java Naming and Directory Interface 32, 113, 141, 223 Java Naming Directory Interface support 93 Java Native Interface 53 Java packages 272 Java perspective 261 Java project 160 Java runtime environment 40 Java stand-alone program 150 Java Transaction API 24, 40, 155 Java Transaction Service 24 Java user-defined functions 24 Java Virtual Machine 40, 234 java.lang.Exception 158 java.lang.String 125 java.rmi.RemoteException 157 java.sql 113, 116 java.sql.Exception 33 java.util.HashMap 247

java.util.Properties 125 javac 117119 JavaMail 40 JavaServer Pages 38, 90 javax.ejb.EJBException 157 javax.naming 113, 116 javax.sql 113, 116 javax.transaction.UserTransaction 195 JCA Authentication 134 JCC 22 JCL INCLUDE statement 70 JDB7712 23 JDB8812 23 JDBC 19, 247 JDBC 1.2 specification 24 JDBC 2.0 specification 22, 24, 113 JDBC 3.0 specification 21, 24, 32 JDBC and SQLJ compared 110 JDBC authentication 129 JDBC driver 21 JDBC Driver Provider 54 JDBC Driver Provider (XA) 52, 80 JDBC driver types 21 Type 1 21 Type 2 21 Type 3 21 Type 4 21 JDBC fundamentals 20 JDBC packages 32 JDBC parameter markers 114 JDBC program preparation 117 JDBC provider 53 JDBC type 4 XA driver 24 JDBC/SQLJ 2.0 Driver 21 JDBC-ODBC bridge 21 JDO 104 JIT compiler 235 JMS 40 JNDI 32, 113, 141, 223 JNDI lookup 51 JNDI name 51, 166 JNDIName 59, 279, 290, 309 JNI 53 JSP 38, 90, 105, 153 Benefits 91 JTA 24, 40, 155 JTA/XA transaction 80 JTS 24, 40 Just In Time compiler 235 JVM 40, 151, 234, 282 JVM heap size 234 JVM System property db2.jcc.propertiesFile 72

K
Kerberos 128 KERBEROS_SECURITY 130 Key 16

Index

327

L
Last participant optimization 199 LDS 10 Lfecycle methods 283 libjava_g 235 LIBPATH 26, 235 Lifecycle methods 96 Limit key 12 Linear data sets 10 LINKLIST 70 Linklist 202 LOB 10, 249 LOB column 247 LOB locators 31 Local dynamic statement cache 18 Local interface 264 Local JDBC Provider (RRS) 51, 223 Local reference 262 Local transactions 192 LocalHome class 271 Lock duration 206 Lock mode 210 Lock mode compatibility 211 LOCKSIZE ANY 210, 217 PAGE 210 ROW 210 TABLE 210 TABLESPACE 210 Logical clustered environment 43 Logical Unit of Work 192 LPAR 22 LUW 192

MVC 150, 298 MVC model 253 MVC1 246 MVC2 246 MVS console 43

N
Namespace 290 Navigator view 273 ND 51 Network deployment 43, 51 NO WLM ENVIRONMENT 5 Node 81 Node scope 81 Nonpartitioned secondary index 13 non-XA JDBC provider 79 non-XA resource compliant 200 NPSI 13 Nullable columns 220 NULLID 272 NULLID collection 204 NULLID qualifier 249 NUMPARTS 10

O
Object Request Broker 282 ODBC 3, 21, 140 OLE DB 3 OLTP support 105 Omegamon 230 ON DELETE CASCADE 16 ON DELETE SET NULL 16 One-phase commit 79 Online checking 188 OSA Express 222 Overqualified predicates 215 Overriding lock mode 212 OW54622 233 OWNER 120

M
Manage WebSphere variables 64 Map.mapxmi 273 Max Connections 225 MAX REMOTE ACTIVE 229 MAX USERS 229 MAXDBAT 229 Maximum Heap Size 235 MAXROWS 1 217 MDB 101 Meet in the middle 183 Message Driven Beans 38 Message driven Beans 101 Metadata 260 Metadata stored procedures 2829 META-INF 282 META-INF folder 265 Method abstract declaration 263 Method signature 263 MIME types 246 Min Connections 225 Model View Controller 246 Models 246 Model-View-Controller 150 MSU 204

P
Package 17 Package lists 19 Package not found exception 187 Page locks 210 Parallel sysplex 206 Parameter marker 114 PARTITION BY 12 Partitioned table space Index-controlled partitioning 12 Limit key 12 Table-controlled partitioning 12 Partitioning clause 12 Partitioning indexes 12 passivate() 96 Password 128 PATH 26 Performance considerations 231

328

DB2 for z/OS and WebSphere: The Perfect Couple

PKLIST 19 Plan 17 PMI 222 PQ36011 22 PQ62695 29 PQ72453 29 PQ78165 29 PQ80079 24, 52 PQ80841 23, 26, 52 PQ83561 29 PQ90208 22 PQ90210 22 PQ90211 22 PQ95284 23 PQ95881 30 PreparedStatement interface 115 PreparedStatements 228 Presentation servlet 297 Primary key 16 printTrace 33 Private protocol 18 Product Provider 36 Profile customization 146 Programmatic authentication 135 Project navigator 270 Promote to Local Interface 264 PROVIDER_URL 142 Purge Policy 226

Resource interfaces 198 Resource Managed Local Transaction 199 Resource manager 193 Resource recovery services 7 Resource transaction isolation 199 ResultSet 31, 146 ResultSet interface 114 ResultSet.getxxx 116 ResultSets 228 Resync IP port 208 Reverse engineering 183 RMI 93 RMLT 199 Rollback 194 rollback() 195 Root package name 171 Row locks 210 ROWID 216, 259 RR 146, 187, 212, 220 RRS 7, 22, 51, 198, 223 RRSAF 7 RS 146, 187, 212, 220 Run-as 132 RuntimeException 157

S
Sample scenario setup 50 SCA 205 Schemas 19 SDSNLOD2 70 Searched update 216 Secondary indexes 13 Security 2 Deployment descriptor 132 Security policy 128 securityMechanism 129, 131 SEGSIZE 10 Self-referencing constraint 16 SERIALIZABLE 146 Serializable interface 265 Serialized profile 118119, 146, 275 Servant 40 Servant region 233 server_region_dynapplenv_jclparms 233 server_region_dynapplenv_jclproc 233 Servlet 38, 90, 105, 179, 246 Benefits 91 Considerations 91 Session Bean 38, 93, 151, 182 Session facade 102 SessionContext 156 SET CURRENT PACKAGE PATH 124 SET CURRENT PACKAGESET 123 SET CURRENT SCHEMA 122 SET CURRENT SQLID 121 SET SCHEMA 122 -SET SYSPARM 28, 230 SET TRANSACTION ISOLATION LEVEL 187, 213 setAutoCommit 177 setDB2CurrentPackagePath 33 Index

Q
QUALIFIER 120, 122

R
RACF user ID 129 Rational Clearcase 161 RDB to EJB 259 RDBMS 38 READ COMMITTED 146 READ STABILITY 217 Read stability 146, 187, 212 READ UNCOMMITTED 145 Reap Time 224225 Recoverability 2 Recoverable Resource Services 198 Redbooks Web site 322 Contact us xxiii Referential constraint 16 Referential integrity definition 263 REGION 234 Relational database management systems 2 Relationship implementation 99 Remote interface 282 Remote Method Invocation 93 Remote vs. local interface 151 RemoteException 157 REPEATABLE READ 146, 217 Repeatable read 146, 187, 212 Res-auth 133, 135 Resource adapters 39

329

setDB2CurrentPackageSet 33 setJccLogWriter 33 setRollbackOnly 156157 setRollbackOnly() 196 Setters 272 Setting the client strings 137 setTransactionIsolation() 213 setXXX 125 Share lock 211 Shareable connection 224 Shared Communications Area 205 Simple Object Access Protocol 104 Single resource global transaction 199 SIX-lock 211 S-lock 211 SOAP 104 SOAP message 104 Software configuration 222 SP 102 Special registers 121 CURRENT PACKAGE PATH 124 CURRENT PACKAGESET 123 CURRENT SCHEMA 122 CURRENT SQLID 121 SQL 13 Data Control Language 14 Data Definition Language 14 Data Manipulation Language 14 SQL statement coprocessor 14 SQL warnings 158 SQL/Bindings 15 SQL/Foundation 15 SQL/Framework 15 SQL/JRT 15 SQL/OLB 15 SQL/PSM 15 SQL/XML 15 SQLAntScripts directory 171 SQLDA 28 SQLException 158 SQLJ 19, 79, 247 Deployment on WAS 189 Host variables 173 Java packages 116 Online checking 188 runtime 147 sqlj 112, 118, 140 SQLJ customization 187 SQLJ customization script 275 SQLJ customization script folder 161 SQLJ exploitation 100 SQLJ Java source folder 161 SQLJ program preparation 117 SQLJ runtime classes 27 SQLJ runtime library 146 SQLJ support 104 SQLJ translator 140 SQLJ translator class name 161 SQLJ translator JAR file 160 sqlj.customize.xml 277

sqlj.project.properties file 171 sqlj.runtime 116 sqlj.zip 2627 SQLJAntScripts 274 SQLSTATE 33 SQLWarning 158 ssnmDBM1 5 ssnmDIST 5 ssnmMSTR 4 ssnmSPAS 5 Stale connection 224 startCommandArgs 70 Stateful session Bean 96, 106 stateless Bean 232 Stateless failover 94 Stateless session Bean 106, 290 Stateless session Beans 94 Stateless vs. stateful 151 Statement cache size 227 Statement interface 114 Static SQL 14, 275 Static SQL vs. dynamic SQL 230 -staticpositioned 120 STEPLIB 202 Storage groups 10 Stored procedure 107 Stored procedures 102 Benefits 102 Considerations 103 Structured Query Language 13 Struts 299 struts-config.xml 302 Sun Microsystems 21 Symbolic environment variables 64 Sync to os 136 Sync to thread 290 SYSIBM.INDOUBT 30, 205 Sysplex 44 Sysplex Distributor 208 SYSSTC service class 234 System Administrator 37 System exception 157 System services address space 4

T
T4XAIndbtPkg 30 Table spaces 10 Large object 10 Partitioned 10 Segmented 10 Simple 11 Table-controlled partitioning 12 TCP/IP 78, 208, 234 TCPALVER 130 Team support 161 The big picture 152 Thread identity support 131, 135 Three part table name 203 TLD files 301 Tool provider 37

330

DB2 for z/OS and WebSphere: The Perfect Couple

Top down 183 TRANSACTION _READ_UNCOMMITED 214 Transaction context 194 Transaction coordinator 193 Transaction demarcation 155, 194 Transaction deployment descriptors 217 Transaction isolation 210 Transaction isolation levels 218 Transaction management 97 Transaction types 196 TRANSACTION_NOT_SUPPORTED 232 TRANSACTION_READ_COMMITTED 214, 220 TRANSACTION_REPEATABLE_READ 214, 220 TRANSACTION_SERIALIZABLE 214, 220 TRANSACTION_SUPPORTS 232 Transactional locks 210 TSO attachment facility 6 Two phase commit 22, 24, 192 Two phase commit considerations 206 Type 2 Driver authentication 130 Type 4 Driver authentication 129 Type 4 XA connectivity 23, 80

W
W502002 223 WAS 35 WAS transaction manager 181, 204 was.env file 75, 77 Web application archives 39 Web container 38 Web modules 38 WEB project 160 Web services 93, 104 Web Services Definition Language 104 WebSphere Application Server Architecture 40 Cell 51 Scope 55 WebSphere bindings 270 WebSphere Commerce 47 WebSphere connection pooling 222 WebSphere Everyplace 48 WebSphere extensions 187 WebSphere family 47 WebSphere Flashes 45 WebSphere for z/OS Introduction 35 WebSphere Foundation 47 WebSphere Information Center 42 WebSphere Installer 42 WebSphere MQ 101 WebSphere Portal 47 WebSphere Studio Application Developer 37, 100, 112, 230 SQLJ support 159 WebSphere transaction isolation level 217 WebSphere transaction management 194 WebSphere Voice 48 WITH clause 214 WITH CS 214 WITH RR 212, 214 WITH RS 212, 214 WITH UR 214 Wizard 269 WLM 5, 40 WLM classification 232 WLM Dynamic Application Environment 233 WLM established stored procedure 5 Work file database 9 WSAD 37, 100, 112, 159, 185, 230, 249 Container managed transactions 173 Create a new server 161 Directory structure and files 170 Enable SQLJ support 168 JAAS entry 163 SQLJ CMP beans 166 Generate the custumization script 170 SQLJ Customization Script 168 User-managed persistence 172 WSAD preferences 160 WSAD wizard 290 WSDL 104

U
UDB for z/OS and OS/390 Address spaces 4 U-lock 211 Uncommitted read 145, 187, 212 Uncustomized SQLJ 146 Unique indexes 12 Universal Driver for SQLJ and JDBC 22 Universal JDBC Driver Provider 79, 200, 223 Universal JDBC Driver Provider (XA) 201, 223 UNIX System Services 110 Unshareable connection 224 Unused Timeout 226 Update cursor 215 Update lock 211 UQ85128 52 UR 145, 187, 212 USE AND KEEP EXCLUSIVE LOCKS 212 USE AND KEEP SHARE LOCKS 212 USE AND KEEP UPDATE LOCKS 212 user ID 128 USERID_ONLY_SECURITY 129 User-managed persistence 172 UserTransaction interface 155, 195 UserTransaction.begin() 195 Utility methods 173

V
Verbose Garbage Collection 235 View component 296 Views 246 Virtual Host 311 Virtual Storage Access Method 10 VSAM 10 VSAM control interval size 10 VTAM 234

Index

331

wsOptimisticRead 219 wsOptimisticUpdate 219220 wsPessimisticRead 219 wsPessimisticUpdate 219 wsPessimisticUpdate-Exclusive 219 wsPessimisticUpdateNo-Collisions 219 wsPessimisticUpdate-WeakestLockAtLoad 219

X
X/Open transaction 198 XA 51 XA distributed transaction support 24 XA driver 22, 24 XA specification 198 XA standard 198 XA transaction 80, 223 XID 205 X-lock 211 XML 38, 104, 267 XML enhancements 2 XML file 171

Z
Z parameter 77 z/Architecture mode 234 z/OS Application Connectivity to DB2 for z/OS and OS/390 24 z/OS security options 136 z/OS UNIX System Services 30, 110 z990 222 zAAP 103, 204 zSeries Application Assist Processors 103

332

DB2 for z/OS and WebSphere: The Perfect Couple

DB2 for z/OS and WebSphere: The Perfect Couple

Back cover

DB2 for z/OS and WebSphere: The Perfect Couple


Configure the DB2 Universal Driver with WebSphere Application Server for z/OS Use SQLJ within WebSphere Studio Application Developer Sample application showing SQLJ support for CMP EJBs
DB2 for z/OS is a high performance DBMS, with a very strong reputation in high volume transaction workloads based on relational technology. WebSphere Application Server is a transaction monitor based on object-oriented technology, very much in sync with the J2EE standard. Can we marry the object world and relational world to create a high-volume, high-performance end-to-end OLTP environment? The answers can be found in this IBM Redbook. This book gives a broad understanding of the installation, configuration, and use of the IBM DB2 Universal Driver for SQLJ and JDBC in a DB2 for z/OS and OS/390 Version 7, and DB2 for z/OS Version 8 environment, with IBM WebSphere Application Server for z/OS for z/OS Version 5.02. It describes both type 2 and type 4 connectivity (including the XA transaction support) from a WebSphere Application Server on z/OS to a DB2 for z/OS and OS/390 database server. This publication also demonstrates the advantages of SQLJ in a DB2 environment, the SQLJ support in the IBM application development tool WebSphere Studio Application Developer, as well as the SQLJ support for Enterprise JavaBeans using container-managed persistence.

INTERNATIONAL TECHNICAL SUPPORT ORGANIZATION

BUILDING TECHNICAL INFORMATION BASED ON PRACTICAL EXPERIENCE


IBM Redbooks are developed by the IBM International Technical Support Organization. Experts from IBM, Customers and Partners from around the world create timely technical information based on realistic scenarios. Specific recommendations are provided to help you implement IT solutions more effectively in your environment.

For more information: ibm.com/redbooks


SG24-6319-00 ISBN 0738491861

Das könnte Ihnen auch gefallen