Драйвер IBM DB2 Driver for JDBC and SQLJ имеет свойство источника данных под названием useRowsetCursor. Значение по умолчанию для этого свойства равно true. Это означает, что драйвер всегда будет пытаться использовать многострочную выборку (MRF) для прокручиваемых курсоров при условии поддержки такой выборки сервером. Это свойство позволяет приложению иметь возможность при необходимости отключить MRF. Поддержка MRF для курсоров с прямым просмотром отсутствует. Кроме того, T2zos (DB2 V9 for z/OS) пока не поддерживает MRF.
В настоящее время имеется три public-интерфейса для поддержки MRF:
public void setUseRowsetCursor (boolean useRowsetCursor);public boolean getUseRowsetCursor ();public boolean getUseRowsetCursor (java.util.Properties properties);
Однако это не является общим решением для T2zos. Причина заключается в том, что T2zos требует, , чтобы поддержка rowset (наборов строк) значения по умолчанию false или unset. Это требование вызывает необходимость замены новым свойством текущего свойства useRowsetCursor (это свойство рассматривается ниже в разделе Новое свойство соединения). Кроме того, новое свойство для T2zos используется и для курсоров с прямым просмотром, и для прокручиваемых курсоров. Новая поддержка MRF для T2zos (DB2 V9 for z/OS) включена в драйверах IBM DB2 Driver for JDBC and SQLJ версий 3.7.xx, 3.51.xx, 4.1.xx и более новых.
Что такое многострочная выборка
Многострочная выборка позволяет извлекать (FETCH) ноль или более строк из таблицы результатов. Вместо выборки одной строки можно выбрать набор строк, называемый rowset.
Как показано на рисунке 1, выбирая несколько строк, приложения уменьшают количество SQL-вызовов и могут выполнить выборку набора строк при помощи единственного оператора FETCH. Это приводит к уменьшению использования SQL API (Application Programming Interface) и к уменьшению загрузки процессора для данной функции приложения.
Рисунок 1. Однострочная выборка по сравнению с многострочной
Новое свойство соединения, связанное с MRF, называется enableRowsetSupport. Возможные значения этого свойства:
NOT_SET(значение по умолчанию)YESNO
Если свойство соединения enableRowsetSupport установлено в YES или NO, оно замещает текущую настройку useRowsetCursor.
Для T2zos, если enableRowsetSupport установлено в значение NOT_SET, это означает, что поддержка MRF отсутствует. Для T4 и T2u значение NOT_SET приводит к использованию текущего значения свойства useRowsetCursor, значение по умолчанию которого равно true. Это означает, что будет использоваться MRF только для прокручиваемых курсоров, если сервер поддерживает их. Пользователи T4 и T2u могут отключить поддержку MRF, установив useRowsetCursor в значение false или enableRowsetSupport в значение NO.
Для разрешения MRF установите enableRowsetSupport в значение YES. T2zos будет использовать MRF как для прокручиваемых курсоров, так и для курсоров с прямым просмотром, если сервер их поддерживает. T4 и T2u будут использовать 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);
UPDATE или DELETE с многострочным позиционированием
Драйвер IBM Data Server Driver for JDBC and SQLJ поддерживает методику выполнения позиционированных операций UPDATE или DELETE, отвечающих стандарту JDBC 1. Для курсоров rowset синтаксис позиционированной операции UPDATE JDBC 1 должен знать о rowset. Формат синтаксиса таков:
update table set.... where current of cursor for row N of rowset
Если приложение хочет использовать позиционированные операции UPDATE JDBC 1, оно должно нести ответственность за корректное позиционирование в выражении UPDATE/DELETE.
Однако текущие t2zos-приложения все еще используют позиционированные выражения UPDATE JDBC 1 и следующий формат:
update table set....where current of cursor
Следовательно, поведение отличается при поддержке rowset. UPDATE оказывает влияние на весь rowset, а не только на одну строку. Вот почему настройка по умолчанию для поддержки t2zos rowsets установлена в значение 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 для обновления или удаления данных в источнике данных, поддерживающем многострочный FETCH, позиционированное выражение UPDATE или DELETE может обновлять или удалять несколько строк тогда, когда вы ожидаете от него обновления или удаления только одной строки.
Чтобы избежать нежелательных операций UPDATE или DELETE, можно выполнить одно из следующих действий:
- Использовать обновляемый
ResultSetдля извлечения и обновления одной строки. - Использовать оператор
FOR ROW n OF ROWSETв выраженияхUPDATEилиDELETEдля идентификации конкретной изменяемой или удаляемой строки.
В листинге 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);
// Разрешить поддержку MRF. Для запрета MRF установить setEnableRowsetSupport
// в 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");
// Получить значение Rowset support. Если MRF разрешен,
// должно возвратиться значение
int RowSet = ((com.ibm.db2.jcc.DB2BaseDataSource)ds).getEnableRowsetSupport();
System.out.println("\nRow Set Support value :" +RowSet);
System.out.println("\n");
// Установить тип курсора в прокручиваемый.
// Измените следующее выражение, если хотите установить
// тип курсора в TYPE_FORWARD_ONLY
java.sql.Statement s = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// Создать таблицу
s.executeUpdate ("create table TestQBatch (col1 int)");
// Заполнить таблицу данными.
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) + " ");
}
// Если MRF разрешен, ResultSet.getFetchSize() всегда будет
// возвращать значение > 1.
int ActualResult = rs.getFetchSize();
System.out.print ("\n\nFetch Size : " +ActualResult);
// Удалить созданную таблицу.
s.executeUpdate("DROP TABLE TestQBatch");
System.out.println("\n\nTest case Ends !!! ");
con.commit();
}
}
|
Как проверить, использует выборка MRF или нет
Запустите пример Java-программы, приведенной в листинге 1, на машине T2zos (DB2 V9 for z/OS) с установленным драйвером IBM DB2 Driver for JDBC and SQLJ версии 3.7.xx, 3.51.xx, 4.1.xx или новее. Найдите файл JCC-трассировки под названием jccTrace.txt. Как упоминалось ранее, если на сервере T2zos, поддерживающем MRF, свойство enableRowsetSupport установлено в значение YES, T2zos выполняет подготовку запроса для курсоров с указанием WITH ROWSET POSITIONING.
Если трассировочный файл jccTrace.txt содержит строку WITH ROWSET POSITIONING, это означает, что MRF разрешена. Если MRF запрещена, выражения FETCH готовятся без позиционирования rowset. То есть, в этом случае вы не найдете строки WITH ROWSET POSITIONING в трассировочном файле.
Можно также определить, активна MRF или нет для данного ResultSet, путем вызова ResultSet.getFetchSize(). Если возвращенное значение для fetchSize больше единицы, MRF использовалась. Отметим, что это вызов по ResultSet, а не PreparedStatement
- Из-за ограничений DB2 rowset-курсор (MRF) не совместим с прогрессивной потоковой передачей данных (progressive streaming) в T2zos (Fetch Continue).
- В T2zos при установке
enableRowsetSupportв значениеYES, T2zos будет выполнять подготовку выражений сWITH ROWSET POSITIONINGдля курсоров, если сервер поддерживает MRF. Однако если в курсоре присутствуют поляlobsилиxmlи прогрессивный поток настроен на значение по умолчанию или включен, MRF для выражений выборки будет отключаться. Выражение выборки будет подготавливаться заново без позиционирования набора строк. - T2zos не знает, является ли курсор, возвращаемый из хранимой процедуры, набором строк (rowset) или нет, поэтому драйвер t2zos разрешает только выборку одиночной строки для хранимой процедуры.
- T2zos не будет поддерживать rowset-курсоры lob или xml, возвращаемые из хранимой процедуры и являющиеся прогрессивным потоком данных. В этом случае во время вызова продолжения выборки (T2zosCursor.getMoreData_) может генерироваться код -225.
- Хранимые java-процедуры T2zosбудут отключать поддержку наборов строк, если в курсоре присутствует lob или xml.
Используя многострочную выборку (Multi-row FETCH - MRF), можно улучшить производительность по сравнению с извлечением одной строки в каждом выражении FETCH. Данная статья должна помочь вам понять, что такое MRF и как ее можно использовать. В ней представлен пример Java-программы, которая демонстрирует, как можно настроить MRF в приложении. Объясняется также, как проверить, использует выборка MRF или нет.
- Примите участие в обсуждении материала на форуме.
- Оригинал статьи Multi-row fetch support with type 2 connectivity in DB2 V9 for z/OS (EN).
- В разделе DB2 for z/OS на сайте developerWork размещены ресурсы, необходимые для повышения квалификации в DB2 for z/OS.

Правин Р. Согалад (Praveen Sogalad) в настоящее время работает в отделе обеспечения качества Common Application Development for DB2 Universal JDBC Driver (JCC) в IBM India Software Labs, Бангалор, Индия. До этого он был разработчиком приложений в отделе DB2 Samples Development в IBM India Software Labs.