在 DB2 V9 for z/OS 中通过类型 2 连接支持多行获取

简介

IBM DB2 Driver for JDBC and SQLJ 有一个称为 useRowsetCursor 的数据源属性。该属性的默认值是 true,这意味着在服务器支持的情况下,驱动程序将尝试对可滚动游标使用多行获取(MRF)。该属性允许应用程序在必要时将 MRF 设置为 off。还没有针对单进游标的 MRF 支持。另外,T2zos (DB2 V9 for z/OS) 尚未支持 MRF。

目前,MRF 支持有 3 个公共接口:

  • public void setUseRowsetCursor (boolean useRowsetCursor);
  • public boolean getUseRowsetCursor ();
  • public boolean getUseRowsetCursor (java.util.Properties properties);

不过,这不能当成 T2zos 的常规解决方案。这是因为 T2zos 需要行集支持来获得默认的 falseunset。该需求导致需要使用新的属性覆盖当前的 useRowsetCursor 属性(将在下面的 新连接属性 小节进一步阐述该属性)。另外,对于 T2zos,新的属性可用于单进游标和可滚动游标。在 IBM DB2 Driver for JDBC and SQLJ 版本 3.7.xx、3.51.xx、4.1.xx 和更新版本中,都启用了 MRF for T2zos (DB2 V9 for z/OS) 额外支持。

什么是多行获取?

多行获取允许您从结果表中获取 0 行或多行。与获取一个行不同,您可以获取一组行(称为行集)。

图 1 所示,通过获取多个行,应用程序减少了 SQL 调用,并且可以使用一个 FETCH 语句获取行集。这不仅减少 SQL Application Programming Interface (API) 的交叉使用,还减少了应用程序的该函数的 CPU 使用。


图 1. 单行获取和多行获取比较
对比使用和未使用 MRF 的进程流。使用 MRF 时仅有一个获取操作,不使用 MRF 则有多个获取操作。 

新连接属性

与 MRF 相关的新连接属性是 enableRowsetSupport。该属性的可用值包括:

  • NOT_SET(默认值)
  • YES
  • NO

enableRowsetSupport 连接属性设置为 YESNO 时,它将使用 useRowsetCursor 覆盖当前的设置。

对于 T2zos,如果 enableRowsetSupport 的值为 NOT_SET,这意味着没有 MRF 支持。对于 T4 和 T2u,NOT_SET 导致使用 useRowsetCursor 属性的当前值,该属性的默认值为 true。这意味着如果服务器在 T4 和 T2u 上支持它,将仅对可滚动游标使用 MRF。T4 和 T2u 用户可以将 useRowsetCursor 设置为 false 或将 enableRowsetSupport 设置为 NO 关闭该行为。

要启用 MRF,将 enableRowsetSupport 设置为 YES。如果服务器支持,T2zos 将对可滚动游标和单进游标使用 MRF。在未来,T4 和 T2u 可能选择仅对单进游标使用 MRF。

要禁用 MRF,将 enableRowsetSupport 设置为 NO。这意味着 MRF 对所有类型的用户禁用(T2zos、T4 和 T2u)。

下面是用于覆盖 useRowsetCursor 属性的当前设置的新属性:

  • public void setEnableRowsetSupport(int enableRowsetSupport);
  • public int getEnableRowsetSupport();
  • public int getEnableRowsetSupport(java.util.Properties properties);

    多行定位 UPDATEDELETE

    IBM Data Server Driver for JDBC and SQLJ 支持执行遵循 JDBC 1 标准的定位 UPDATEDELETE 操作。对于行集游标,JDBC 1 定位更新语法必须知道行集的存在。该语法必须遵循以下格式:

    update table set.... where current of cursor for row N of rowset

    如果应用程序想要使用 JDBC 1 定位 UPDATE 操作,那么它必须构建正确定位的 UPDATE/DELETE 语句。

    不过,当前的 t2zos 应用程序仍然使用 JDBC 1 定位 UPDATE 语句,其遵循的格式如下:

    update table set....where current of cursor

    因此,行集支持导致不同的行为。UPDATE 影响整个行集,而不是单个行。因此,t2zos 行集支持的默认设置为 false(见 新连接属性 小节)。

    该技术涉及到使用 ResultSet.getCursorName 方法为 ResultSet 获取游标的名称,以及按照以下格式定义定位 UPDATE 或定位 DELETE 语句:

    UPDATE table SET col1=value1…coln=valueN WHERE CURRENT OF cursorname

    DELETE FROM table WHERE CURRENT OF cursorname

    如果您使用 JDBC 1 技术对支持多行获取的数据源中的数据执行 UPDATEDELETE 操作,定位 UPDATEDELETE 语句可能 UPDATEDELETE 多个行,尽管您可能希望它仅 UPDATEDELETE 单个行。

    要避免意外的 UPDATEDELETE 操作,您可以采取以下措施之一:

    • 使用可更新的 ResultSet 一次仅获取和 UPDATE 一个行。
    • UPDATEDELETE 语句中使用 FOR ROW n OF ROWSET 子句, 以识别需要执行 MODIFYDELETE 操作的特定行。

      样例 Java 程序

      清单 1 使用一个样例 Java 程序,它演示如何使用新的 enableRowsetSupport 连接属性覆盖当前的 useRowsetCursor 属性。

      该程序将 enableRowsetSupport 设置为 YES,这意味着将启用 MRF。


      清单 1. 样例程序:connectionInfo_MRF.java
      import java.sql.*;
      
      public class connectionInfo_MRF 
      {
       public static void main(String[] args) throws Exception
       {
        	System.out.println("\nTest case begins !!!\n ");
                
        	javax.sql.DataSource ds = new com.ibm.db2.jcc.DB2SimpleDataSource();
                
        	((com.ibm.db2.jcc.DB2BaseDataSource) ds).setServerName("ServerName"); 
        	((com.ibm.db2.jcc.DB2BaseDataSource) ds).setPortNumber(portNumber);
        	((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDatabaseName("databaseName");
        	((com.ibm.db2.jcc.DB2BaseDataSource) ds).setDriverType(2); 
                
        	// Enable MRF support. To disable MRF, set setEnableRowsetSupport 
        	// to com.ibm.db2.jcc.DB2BaseDataSource.YES
        
         	int setValue = com.ibm.db2.jcc.DB2BaseDataSource.YES;
        	((com.ibm.db2.jcc.DB2BaseDataSource)ds).setEnableRowsetSupport(setValue);
        
        	((com.ibm.db2.jcc.DB2BaseDataSource) ds).setTraceFile("jccTrace.txt");
        
        	System.out.println(((com.ibm.db2.jcc.DB2BaseDataSource) ds).getJccVersion());
        
        	java.sql.Connection con = ds.getConnection("userName", "passWord");
        
        	// Get  Rowset support value. When MRF is enabled this should return value 1.
        	int RowSet = ((com.ibm.db2.jcc.DB2BaseDataSource)ds).getEnableRowsetSupport();
        
        	System.out.println("\nRow Set Support value :" +RowSet);
        	System.out.println("\n");	
        
        	// Set the cursor type to scrollable.
        	//Modify the below statement if you want the cursor type to be  TYPE_FORWARD_ONLY
        	java.sql.Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
          	                                           ResultSet.CONCUR_READ_ONLY);
        	// Create table
        	s.executeUpdate ("create table TestQBatch (col1 int)");
        
        	// Populate tables with data.
        	for (int i =1; i less than 1000; i++)
        	{
      		  s.executeUpdate ("insert into TestQBatch values (" +i+ ")");
        	}
        
        	java.sql.ResultSet rs = s.executeQuery("Select * from TestQBatch");
        
        	while (rs.next()) 
        	{
        			System.out.print (rs.getInt (1) + "  ");
        	}
        
        	// When MRF is enabled, ResultSet.getFetchSize() should alway return value > 1.
        	int ActualResult = rs.getFetchSize();
        
        	System.out.print ("\n\nFetch Size : " +ActualResult);
        
        	// Drop the table created.
       	s.executeUpdate("DROP TABLE TestQBatch");
        
        	System.out.println("\n\nTest case Ends !!! ");
        
        	con.commit();
        
       }
      }
      
      

      限制

      • 由于受到 DB2 的限制,行集游标(MRF)与 T2zos (Fetch Continue) 中的渐进式流不兼容。
      • 在 T2zos 中,如果您将 enableRowsetSupport 设置为 YES,并且服务器支持 MRF,那么 T2zos 将为游标准备 WITH ROWSET POSITIONING。不过,如果在游标中出现大对象或 XML,并且渐进式流使用默认值或设置为 on,将对 FETCH 语句关闭 MRF(OFF )。将重新准备 FETCH 语句,并且不包含行集定位。
      • T2zos 不知道从存储过程返回的游标是不是一个行集,因此 t2zos 驱动程序仅允许对存储过程执行单行获取。
      • T2zos 不支持从存储过程返回的并且是渐进式流形式的大对象或 XML。在获取继续 (T2zosCursor.getMoreData_) 调用期间,该情况可能导致抛出 -225 sqlcode。
      • 如果游标中出现大对象或 XML,T2zos java 存储过程将关闭行集支持。

        结束语

        使用多行获取 (MRF),您可以获得比使用 FETCH 语句每次获取一行更佳的性能。本文帮助您理解了 MRF 及其使用方式。此外,还通过一个简单的样例 Java 程序演示如何在 Java 程序中设置 MRF,并解释如何确定是否使用了 MRF。

    • 转自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0909rowsetdb2zos/index.html

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15082138/viewspace-621615/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15082138/viewspace-621615/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值