应用程序和数据库之间接口上的跟踪数据为开发人员提供了发现程序错误和优化数据库访问所需的信息。DB2® Legacy JDBC™ Driver 基于 DB2 Call Level Interface (CLI) 层,它允许通过 CLI 配置的变化进行 JDBC 或 CLI 跟踪。而新的 DB2 Universal JDBC Driver 不再基于 DB2 CLI 层,所以那些已知的跟踪功能不再可用。但是 DB2 Universal JDBC Driver 通过对某些驱动程序属性的设置,同样提供了跟踪功能。本文首先提到 DB2 Legacy JDBC Driver 基于 CLI 的跟踪功能,然后描述新的 DB2 Universal JDBC Driver 的跟踪功能,并通过例子演示如何使用这些跟踪功能。
简介 —— 为什么需要 JDBC 跟踪?
JDBC 跟踪可以为 Java 应用程序开发人员提供有价值的信息,以帮助他们进行数据库应用程序的开发。在下面这些例子中,您需要知道如何执行 JDBC 跟踪:
搜寻程序逻辑错误或初始化错误 —— 错误的 URL 可能导致数据库连接失败,预期仅执行一次的查询可能被多次调用,定义有误的事务可能导致数据库的不一致,等等。在所有这些情况中,往往可以用跟踪数据来发现问题的起因。
性能调优 —— 在多层环境中,性能问题难于检测,因为首先必须确定应该对性能问题负责的层 - 应用程序、网络或数据库。通过分析跟踪数据流中函数调用的入口/出口时间戳,就可以发现是哪一层导致性能问题。
理解第三方的软件 —— 当您在使用第三方的软件时,由于手头上没有源代码,所以常常难于判别问题。因此,跟踪信息或许有助于更好地理解第三方软件是如何实现数据库接口的。
DB2 Legacy JDBC Driver 与 DB2 Universal JDBC Driver
DB2 Legacy JDBC Driver 是老的 type 2 驱动程序,老版本的 DB2 中自带了这种驱动程序。该驱动程序建立在 DB2 CLI 的基础上,DB2 CLI 是一种 DB2 本地 C 调用级接口,它本身建立在一些其他层之上。作为 type 2 驱动程序,它要求安装 DB2 客户机。DB2 Legacy JDBC Driver 包含在文件 db2java.zip 中。
DB2 version 8 附带了一种新的 JDBC 驱动程序,即 DB2 Universal JDBC Driver。该驱动程序是从头开始编写的,在架构中它是一个抽象 JDBC 处理器,用于支持 type 2 和 type 4 连接。在建立连接时,应用程序通过使用不同的 URL 语法来选择所需类型的连接。DB2 Universal Driver 使用 Distributed Relational Database Architecture (DRDA) 协议与 DB2 服务器通信,它建立在一个 Java 客户机层之上,这个层替代了 CLI 以及其下的很多层。只有 type 2 才要求安装 DB2 客户机,type 4 不需要 DB2 客户机。DB2 Universal JDBC Driver 包含在文件 db2jcc.jar (JCC 表示 Java Common Connectivity)中。虽然 DB2 Legacy Driver 仍然受支持,但在将来它将完全被 DB2 Universal JDBC Driver 替代。
用 DB2 Legacy JDBC Driver Type 2 进行跟踪
基于 CLI 的 DB2 Legacy JDBC Driver Type 2 为应用程序开发人员提供了两种不同的跟踪方法:
在 JDBC 层跟踪 —— 在这种情况下,所有 JDBC 函数调用都被跟踪。跟踪信息包括:函数调用序列、输入和输出参数、返回代码以及错误和警告消息。
在 CLI 层跟踪 —— DB2 Legacy JDBC Driver Type 2 在内部将所有 JDBC 函数调用映射到 CLI 函数调用上。因此,使用这种驱动程序的 Java 程序也可以在 CLI 层启动跟踪。跟踪信息仍然是一样的 —— 函数调用、参数、返回代码和消息 —— 但位置却是在更低级的 CLI 层。
上述两种跟踪都是通过 CLI 初始化文件 db2cli.ini 来控制的。在 Windows 系统上,文件 db2cli.ini 位于目录 %DB2PATH% (默认情况下是 C:\Program Files\IBM\SQLLIB)中。在 UNIX/Linux 系统上,该文件位于实例所有者的 $HOME 目录中,这个目录在 sqllib/cfg 目录下。
为了在 JDBC 层启动跟踪,在 db2cli.ini 文件中的 [COMMON] 下建立以下条目:
清单 1. 用于 JDBC 跟踪的 CLI 关键字[COMMON]
JDBCTrace=1
JDBCTracePathName=<trace directory>
可选地,也可以指定关键字 JDBCTraceFlush=1。在此情况下,每个跟踪条目被分开来写到跟踪文件中,之后关闭跟踪文件,再重新打开跟踪文件。这样可以保证,即使 Java 程序崩溃也不会丢失跟踪条目。但是另一方面,这个选项也极大地降低了性能。
当第一次建立数据库连接时,文件 db2cli.ini 中的条目是只读的,因此,对文件 db2cli.ini 的更改不会影响现有的数据库连接。
下面的示例程序可用于测试使用 DB2 Legacy JDBC Driver Type 2 情况下的 JDBC 跟踪。在本文的后续部分,该示例程序还用于演示 DB2 Universal JDBC Driver 的跟踪功能。
清单 2. 使用 Legacy Driver Type 2 情况下用于跟踪测试的示例代码public class LegacyTraceExample
{
public static void main(String[] args) {
try {
// load driver
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();
// set connection properties
String databaseUrl = "jdbc:db2:sample";
// get connection
java.sql.Connection con =
java.sql.DriverManager.getConnection(databaseUrl, "user", "password");
// execute a query
java.sql.Statement stmt = con.createStatement();
String query = "SELECT COUNT(*) FROM SYSCAT.TABLES";
java.sql.ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
System.out.println("\n" + query + " = " + rs.getInt(1));
}
rs.close();
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
因为该示例程序只用于演示跟踪功能,因此这里最小限度地使用了异常处理。程序首先动态装载 DB2 Legacy JDBC Driver Type 2。然后通过 JDBC 驱动程序管理器建立到数据库的一个连接,并执行对系统目录表的一个简单查询。
db2cli.ini 文件中的下列条目在目录 C:\temp 中为示例程序创建一个 JDBC 跟踪。
清单 3. 使用 Legacy Driver Type 2 情况下用于跟踪测试的 db2.cli 条目[COMMON]
JDBCTrace=1
JDBCTraceFlush=1
JDBCTracePathName=c:\temp
用 DB2 Universal JDBC Driver Type 2/Type 4 进行跟踪
DB2 Universal JDBC Driver 不再基于 DB2 CLI 层。对于 type 4 驱动程序的初始化和 type 2 驱动程序的初始化都是如此。由于这个原因,通过 CLI 配置(文件 db2cli.ini)的变化来进行 JDBC 跟踪已经变得不可能。但是,DB2 Universal JDBC Driver 允许通过设置某些驱动程序属性进行跟踪。
当使用 DataSource 接口进行数据库访问时,可以通过该接口的方法来设置跟踪属性。DB2 Universal JDBC Driver 的所有 DataSource 类都继承基类 DB2BaseDataSource,这个基类也定义了用于跟踪的一些属性。
清单 4. DB2 DataSource 类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
下面的例子中使用 DB2SimpleDataSource 进行数据库访问。JDBC 跟踪的配置对于所有 DataSource 类来说其行为都是一样的,并且也独立于 DB2 Universal JDBC Driver 的 type 2 或 type 4 初始化。
下面的示例程序演示了如何通过调用类 DB2BaseDataSource 中定义的方法来启动 JDBC 跟踪。
清单 5. 使用 Universal Driver Type 2/4 (变种 1)情况下的跟踪测试示例代码public class JccTraceExample1
{
public static void main(String[] args) {
try {
// create data source
com.ibm.db2.jcc.DB2SimpleDataSource ds =
new com.ibm.db2.jcc.DB2SimpleDataSource();
// set connection properties
ds.setServerName("localhost");
ds.setPortNumber(50000);
ds.setDatabaseName("sample");
ds.setDriverType(4);
// set trace properties
ds.setTraceDirectory("c:\\temp");
ds.setTraceFile("trace");
ds.setTraceFileAppend(false);
ds.setTraceLevel(com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL);
// get connection
java.sql.Connection con = ds.getConnection("user", "password");
// execute a query
java.sql.Statement stmt = con.createStatement();
String query = "SELECT COUNT(*) FROM SYSCAT.TABLES";
java.sql.ResultS