跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

DB2 应用程序开发: 利用 DB2 Universal JDBC Driver 进行跟踪

在缺少 CLI 层的情况下如何执行 JDBC 跟踪

Dirk Fechner (fechner@de.ibm.com), IT 服务专家, IBM Software Group
作者照片
Dirk Fechner 在 IBM Software Group 中担任一名 IT 服务专家。他的专长领域是分布式平台上 DB2 UDB 的管理和应用程序开发。他拥有 5 年 DB2 UDB 方面的经验,也是一名 IBM 认证的高级 DBA 和 IBM 认证的应用程序开发人员。目前,他在 DaimlerChrysler 为管理员、开发人员和终端用户就各种 DB2 话题提供支持,包括管理任务、应用程序开发以及问题判别。

简介: 应用程序和数据库之间接口上的跟踪数据为开发人员提供了发现程序错误和优化数据库访问所需的信息。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 的跟踪功能,并通过例子演示如何使用这些跟踪功能。

发布日期: 2005 年 6 月 09 日
级别: 初级
访问情况 : 2081 次浏览
评论: 


简介 —— 为什么需要 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.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();
        }
    }
}

首先初始化用于数据库访问的 DB2SimpleDataSource,在这个例子中,它被初始化为 type 4。JDBC 跟踪的配置是通过调用以下方法完成的:

  • setTraceDirectory —— 定义用于写跟踪文件的目录。如果定义一个跟踪目录,则对于每个数据库连接,都创建一个单独的跟踪文件。之所以建议这样做,是因为如果不这样做的话,所有数据库连接的跟踪数据都将被写到同一个跟踪文件 —— 这使得对跟踪文件的分析更加困难。
  • setTraceFile —— 定义跟踪输出所写到的文件。如果指定一个跟踪文件名,以及一个跟踪目录 —— 例如这个例子 —— 对于每个数据库连接,都按照下面的模式创建一个跟踪文件:<trace directory>\<trace file>_<data source type>_<sequential number>。对于示例程序,将创建一个跟踪文件 c:\temp\trace_sds_0。如果没有指定跟踪目录,那么所有数据库连接的跟踪输出都将被写到指定的跟踪文件。在这个例子中,跟踪文件也可以通过完全路径指定。
  • setTraceFileAppend —— 如果文件已经存在,控制是否覆盖跟踪文件。
  • setTraceLevel —— 定义要跟踪的信息。为此,要使用 DB2BaseDataSource 中定义的一些常量。

表 1. DB2 JDBC 跟踪常量

跟踪常量 整数值
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_NONE 0
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTION_CALLS 1
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_STATEMENT_CALLS 2
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_RESULT_SET_CALLS 4
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRIVER_CONFIGURATION 16
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_CONNECTS 32
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DRDA_FLOWS 64
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_RESULT_SET_META_DATA 128
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_PARAMETER_META_DATA 256
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_DIAGNOSTICS 512
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_SQLJ 1024
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_XA_CALLS 2048
com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL -1

在示例程序中,所有跟踪信息都将被收集(com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL)。如果您只想跟踪某些信息,那么可以通过使用 OR 操作符组合跟踪常量(例如 com.ibm.db2.jcc.DB2BaseDataSource.TRACE_STATEMENT_CALLS | com.ibm.db2.jcc.DB2BaseDataSource.TRACE_RESULT_SET_CALLS)。

这种跟踪可能有点问题,因为它要求改变源代码,这一点在所有环境中都是不可取的。如果独立于源代码来定义数据源,例如使用像 WebSphere 这样的应用程序服务器就可以做到这一点,那么,就可以和 Data Source 的定义一起指定跟踪属性。这样一来,就可以在不改变源代码的情况下启动/撤销跟踪。关于这个话题,下面的技术说明给出了更详细的信息:

Enabling DB2 Universal JDBC Driver (JCC) tracing on WebSphere Application Server V5

但是,即使数据源是在源代码中定义的 —— 例如在这个示例程序中 —— 也可以在不改变源代码的情况下控制跟踪。清单 6 展示了不设置跟踪属性的示例程序。


清单 6. 使用 Universal Driver Type 2/4 情况下的跟踪测试示例代码(变种 2)
				
public class JccTraceExample2
{
    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);
            // 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.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();
        }
    }
}

为了在不改变源代码的情况下控制跟踪,可以创建一个单独的配置文件,文件中包含一些跟踪属性。


清单 7. DB2 JDBC 跟踪属性
				
db2.jcc.traceDirectory=c:\\temp
db2.jcc.traceFile=trace
db2.jcc.traceFileAppend=false
db2.jcc.traceLevel=-1

对于这个配置文件没有命名惯例。文件名是在执行 Java 程序时通过选项 -D 指定的。例如,如果配置文件被命名为 jcc.properties,那么程序调用如下:


清单 8. DB2 JDBC 跟踪属性文件
				
java -Ddb2.jcc.propertiesFile=jcc.properties JccTraceExample2

在这个例子中,配置文件和 Java class 文件放在同一个目录中。如果不这样的话,也可以指定配置文件的完全路径。

如果使用配置文件,则不能将跟踪级别指定为常量,而应该使用相应的整数值,例如,对于 TRACE_ALL 是 -1,对于 TRACE_STATEMENT_CALLS | TRACE_RESULT_SET_CALLS 是 6(在这个例子中,这些值被简单相加“2 + 4”)。

由于配置文件中的属性不限于某一个数据源,因此它们自动引用所有数据源。所以,这里生成的跟踪文件名不同于在前一个例子中生成的跟踪文件名。如果同时指定了跟踪目录和跟踪文件,那么对于每个数据库连接,都按照下面的模式创建一个跟踪文件: <trace directory>\<trace file>_global_<sequential number>。对于当前的示例程序,创建的跟踪文件是 c:\temp\trace_global_0。

如果在源代码和配置文件中都指定跟踪属性,则使用源代码中定义的属性。如果要强制使用配置文件中的跟踪属性,则必须用加法覆盖指定配置文件中的跟踪属性。


清单 9. 跟踪属性覆盖的例子
				
db2.jcc.override.traceDirectory=c:\\temp
db2.jcc.override.traceFile=trace
db2.jcc.override.traceFileAppend=false
db2.jcc.override.traceLevel=-1


使用 DB2 Universal JDBC Driver 时的跟踪变量


除了使用 Data Source 之外,也可以使用 DriverManager 接口来建立数据库连接。在这种情况下,可以在数据库 URL 中附加跟踪属性。


清单 10. 使用 Universal Driver Type 2/4 情况下的跟踪测试示例代码(变种 3)
				
public class JccTraceExample3
{
    public static void main(String[] args) {
        try {
            // load driver
            Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();
            // set connection properties
            String databaseUrl = "jdbc:db2://localhost:50000/sample"
                                 + ":traceDirectory=c:\\temp"
                                 + ";traceFile=trace"
                                 + ";traceFileAppend=false"
                                 + ";traceLevel="
                                 + com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL
                                 + ";";
            // 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();
        }
    }
}

如果同时指定了跟踪目录和跟踪文件,则对于每个数据库连接,都按照下面的模式创建一个跟踪文件: <trace directory>\<trace file>_driver_<sequential number>。对于当前的示例程序,创建的跟踪文件是 c:\temp\trace_driver_0。

或者,也可以将跟踪输出重定向到 PrintWriter。在这种情况下,跟踪是通过调用类 com.ibm.db2.jcc.DB2Connection 的方法 setJccLogWriter 启动的。这个方法需要 PrintWriter 和跟踪级别作为参数。


清单 11. 使用 Universal Driver Type 2/4 情况下的跟踪测试示例代码(变种 4)
				
public class JccTraceExample4
{
    public static void main(String[] args) {
        try {
            // create print writer
            java.io.PrintWriter printWriter = new java.io.PrintWriter(
                new java.io.BufferedOutputStream(
                    new java.io.FileOutputStream("c:\\temp\\trace.txt"), 4096), true);
            // 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);
            // get connection
            java.sql.Connection con = ds.getConnection("user", "password");
            // activate trace
            ((com.ibm.db2.jcc.DB2Connection) con).setJccLogWriter(printWriter,
                com.ibm.db2.jcc.DB2BaseDataSource.TRACE_ALL);
            // 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();
        }
    }
}

致谢


我要感谢 Peter Schurr 对本文进行了审校。



下载

描述名字大小下载方法
DB2 Universal JDBC Driver trace samplesdb2jcc_trace_samples.zip4KBFTP|HTTP|Download Director

关于下载方法的信息


参考资料

关于作者

作者照片

Dirk Fechner 在 IBM Software Group 中担任一名 IT 服务专家。他的专长领域是分布式平台上 DB2 UDB 的管理和应用程序开发。他拥有 5 年 DB2 UDB 方面的经验,也是一名 IBM 认证的高级 DBA 和 IBM 认证的应用程序开发人员。目前,他在 DaimlerChrysler 为管理员、开发人员和终端用户就各种 DB2 话题提供支持,包括管理任务、应用程序开发以及问题判别。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management, Java technology
ArticleID=87490
ArticleTitle=DB2 应用程序开发: 利用 DB2 Universal JDBC Driver 进行跟踪
publish-date=06092005
author1-email=fechner@de.ibm.com
author1-email-cc=

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。