db2 jdbc驱动_使用DB2通用JDBC驱动程序进行跟踪

简介-为什么要进行JDBC跟踪?

JDBC跟踪是一种为Java应用程序开发人员提供有价值的信息,以帮助他们进行数据库应用程序开发工作的方法。 以下是一些需要了解如何执行JDBC跟踪的实例示例:

  • 搜索程序逻辑或初始化错误-数据库连接可能由于URL错误而失败,一次又一次地调用预期要执行的查询,由于事务定义不正确而可能导致数据库不一致,并且以此类推。 在所有这些情况下,很有可能可以使用跟踪数据来发现问题的原因。
  • 性能调整-多层环境中的性能问题很难检测,因为必须首先确定负责的层-应用程序,网络或数据库。 通过分析跟踪数据流中函数调用的进入/退出时间戳,可以确定引起性能问题的层。
  • 了解第三方软件-当您使用第三方软件时,由于源代码不可用,通常难以确定问题。 因此,跟踪信息可能有助于更好地了解第三方软件如何实现数据库接口。

DB2旧版JDBC驱动程序与DB2通用JDBC驱动程序


DB2 Legacy JDBC驱动程序是旧的Type 2驱动程序,已在较旧的DB2版本中提供。 它建立在DB2 CLI(DB2本地C调用级别接口)之上,该接口本身也建立在其他几层之上。 作为2类驱动程序,它需要安装DB2客户机。 DB2旧版JDBC驱动程序包含在文件db2java.zip中。

在DB2版本8中,提供了一个新的JDBC驱动程序,即所谓的DB2通用JDBC驱动程序 。 它是从头开始编写的,并被构造为允许类型2和类型4连接的抽象JDBC处理器。 进行连接时,应用程序通过使用不同的URL语法选择所需的连接类型。 DB2通用驱动程序使用分布式关系数据库体系结构(DRDA)协议与DB2服务器进行通信,该驱动程序建立在Java客户机层之上,该客户机层替代了CLI和其下的许多层。 仅对于2类连接,才需要安装DB2客户机; 类型4不需要DB2客户机。 DB2通用JDBC驱动程序包含在文件db2jcc.jar中(JCC表示Java Common Connectivity)。 尽管仍支持DB2 Legacy Driver,但将来它将被DB2 Universal JDBC Driver完全替代。

使用DB2 Legacy JDBC Driver Type 2进行跟踪


基于CLI的DB2传统JDBC驱动程序类型2为应用程序开发人员提供了两种不同的跟踪可能性:

  • 在JDBC层进行跟踪-在这种情况下,将跟踪所有JDBC函数调用。 跟踪信息包括:函数调用顺序,输入和输出参数,返回码以及错误和警告消息。
  • 在CLI层进行跟踪-DB2 Legacy JDBC驱动程序类型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=

(可选)可以指定关键字JDBCTraceFlush=1 在这种情况下,每个跟踪条目都将分别写入跟踪文件。 之后,跟踪文件将关闭并再次打开。 这样可确保即使Java程序崩溃也不会丢失任何跟踪条目。 另一方面,此选项会极大地降低性能。

由于仅在首次建立数据库连接时才读取文件db2cli.ini中的条目,因此对db2cli.ini文件的更改不会影响现有的数据库连接。

当使用DB2传统JDBC驱动程序类型2时,可以使用以下样本程序来测试JDBC跟踪。 在本文的其余部分中,该示例程序还用于演示DB2通用JDBC驱动程序的跟踪功能。

清单2.使用传统驱动程序类型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.使用传统驱动程序类型2进行跟踪测试的db2.cli条目
[COMMON]
JDBCTrace=1
JDBCTraceFlush=1
JDBCTracePathName=c:\temp

使用类型2 /类型4的DB2通用JDBC驱动程序进行跟踪


DB2通用JDBC驱动程序不再基于DB2 CLI层。 对于类型4驱动程序的初始化以及类型2驱动程序的初始化都是如此。 因此,不再可能通过CLI配置更改(文件db2cli.ini)进行JDBC跟踪。 相反,DB2通用JDBC驱动程序允许通过设置某些驱动程序属性进行跟踪。

当使用DataSource接口进行数据库访问时,可以通过此接口的方法设置跟踪属性。 DB2通用JDBC驱动程序的所有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通用JDBC驱动程序的类型2或类型4初始化。

下面的示例程序演示了如何通过调用类DB2BaseDataSource中定义的方法来激活JDBC跟踪。

清单5.使用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 ,在这种情况下,其类型为DB2SimpleDataSource跟踪的配置通过调用以下方法来完成:

  • setTraceDirectory定义写入跟踪文件的目录。 如果定义了跟踪目录,则会为每个数据库连接创建一个单独的跟踪文件。 建议这样做,因为否则所有数据库连接的跟踪数据都将写入单个跟踪文件中,这会使跟踪文件分析变得更加困难。
  • setTraceFile定义将跟踪输出写入的文件。 如果将跟踪文件名与跟踪目录一起指定(例如在示例中),则为每个数据库连接创建根据以下模式的跟踪文件:<跟踪目录> \ <跟踪文件> _ <数据源类型> _ <序列号>。 对于示例程序,将创建跟踪文件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的应用程序服务器,则为true),可以将跟踪属性与数据源的定义一起指定。 这允许在不更改源代码的情况下激活/停用跟踪。

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

清单6.使用通用驱动程序类型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类文件放置在同一目录中。 否则,也可以指定配置文件的完整路径。

如果使用配置文件,则不能将跟踪级别指定为常量,而必须使用相应的整数值,例如对于TRACE_ALL为-1,对于TRACE_STATEMENT_CALLS | TRACE_RESULT_SET_CALLSTRACE_STATEMENT_CALLS | TRACE_RESULT_SET_CALLS TRACE_STATEMENT_CALLS | TRACE_RESULT_SET_CALLS (在这种情况下,只需将值相加= 2 + 4)。

因为配置文件中的属性不限于某个数据源,所以它们会自动引用所有数据源。 因此,生成的跟踪文件名与上一个示例中的文件名不同。 如果指定了跟踪目录以及跟踪文件,则将为每个数据库连接创建根据以下模式的跟踪文件:<跟踪目录> \ <跟踪文件> _global_ <序列号>。 对于示例程序,将创建跟踪文件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时跟踪的变体


除了数据源, DriverManager接口还可以用于建立数据库连接。 在这种情况下,可以将跟踪属性指定为数据库URL的补充。

清单10.使用通用驱动程序类型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();
        }
    }
}

如果指定了跟踪目录以及跟踪文件,则会为每个数据库连接创建以下模式的跟踪文件:<跟踪目录> \ <跟踪文件> _driver_ <顺序号>。 对于示例程序,将创建跟踪文件c:\ temp \ trace_driver_0。

另外,跟踪输出可以重定向到PrintWriter 在这种情况下,通过调用com.ibm.db2.jcc.DB2Connection类的setJccLogWriter方法来激活跟踪。 作为参数,该方法期望使用PrintWriter以及跟踪级别。

清单11.使用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审阅本文。


翻译自: https://www.ibm.com/developerworks/data/library/techarticle/dm-0506fechner/index.html

你可能感兴趣的:(数据库,java,mysql,python,linux)