Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Адаптивная буферизация, разработана для получения любых данных большого объема без затрат на использование серверных курсоров. Приложения могут использовать функцию адаптивной буферизации со всеми версиями SQL Server, поддерживаемыми драйвером.
Как правило, когда драйвер Microsoft JDBC для SQL Server выполняет запрос, драйвер извлекает все результаты из сервера в память приложения. Хотя этот подход сводит к минимуму потребление ресурсов на SQL Server, он может вызвать OutOfMemoryError в приложении JDBC для запросов, которые создают очень большие результаты.
Чтобы разрешить приложениям обрабатывать очень большие результаты, драйвер Microsoft JDBC для SQL Server обеспечивает адаптивную буферизацию. При адаптивной буферизации драйвер извлекает из SQL Server результаты выполнения операторов по мере того, как они требуются приложению, а не все сразу. Драйвер также удаляет результаты, когда приложение теряет к ним доступ. Ниже приводятся примеры ситуаций, когда адаптивная буферизация может быть полезной.
Запрос возвращает результирующий набор очень большого объема. Приложение может выполнить инструкцию SELECT, возвращающую больше строк, чем может уместиться в памяти приложения. В предыдущих версиях приложение должно было использовать серверный курсор, чтобы избежать ошибки OutOfMemoryError. Адаптивная буферизация обеспечивает возможность прямого однократного чтения результирующего набора данных сколь угодно большого размера в режиме только для чтения без использования серверного курсора.
Запрос возвращает очень большиестолбцы SQLServerResultSetилизначения выходных параметров SQLServerCallableStatement: приложение может извлечь одно значение (столбец или параметр OUT), которое слишком велико, чтобы целиком поместиться в памяти приложения. Адаптивная буферизация позволяет клиентскому приложению извлекать такое значение в качестве потока, используя метод getAsciiStream, getBinaryStream или getCharacterStream. Приложение получает значение из SQL Server по мере чтения из потока.
Примечание.
Благодаря адаптивной буферизации драйвер JDBC помещает в буфер только необходимое количество данных. Драйвер не позволяет любому открытому методу контролировать или ограничивать размер буфера.
Настройка адаптивной буферизации
Начиная с драйвера JDBC версии 2.0 по умолчанию используется значение adaptive. Другими словами, чтобы получить адаптивное поведение буферизации, приложению не нужно запрашивать адаптивное поведение явным образом. Но в версии 1.2 по умолчанию использовался режим полной буферизации, поэтому приложение должно было запросить режим адаптивной буферизации явным образом.
Существуют три способа, с помощью которых приложение может запросить выполнение адаптивной буферизации.
Приложение может задать свойству подключения responseBuffering значение "adaptive". Дополнительные сведения о настройке свойств подключения см. здесь.
Приложение может использовать метод setResponseBuffering объекта SQLServerDataSource для установки режима буферизации ответов для всех подключений, созданных посредством объекта SQLServerDataSource.
Приложение может использовать метод setResponseBuffering класса SQLServerStatement, чтобы установить режим буферизации ответов для определенного объекта инструкции.
При использовании драйвера JDBC версии 1.2 приложения должны были приводить объект инструкции к классу SQLServerStatement, чтобы использовать метод setResponseBuffering. Примеры кода в статьях Reading large data sample (Пример считывания большого объема данных) и Reading large data with stored procedures sample (Пример считывания большого объема данных с помощью хранимых процедур) демонстрируют это старое использование.
Однако начиная с драйвера JDBC версии 2.0 приложения могут использовать методы isWrapperFor и unwrap для получения доступа к функциям, предоставляемым поставщиками, без необходимости реализации иерархии класса. Пример кода можно найти в статье Updating Large Data Sample (Пример обновления большого объема данных).
Извлечение большого объема данных с помощью адаптивной буферизации
Когда большие значения считываются однократно с помощью методов get<Type>Stream, а обращение к столбцам ResultSet и выходным параметрам CallableStatement OUT осуществляется в том порядке, в котором их возвращает SQL Server, адаптивная буферизация минимизирует потребление памяти приложением при обработке результатов. При использовании адаптивной буферизации происходит следующее.
Методы get<Type>Stream, определенные в классах SQLServerResultSet и SQLServerCallableStatement, возвращают потоки только для чтения по умолчанию, хотя потоки можно сбросить, если они выделены приложением. Если приложению нужно
resetпоток, оно должно сначала вызвать у этого потока методmark.Методы get<Type>Stream, определенные в классах SQLServerClob и SQLServerBlob, возвращают потоки, которые всегда можно переместить в начальное положение потока без вызова метода
mark.
Когда приложение использует адаптивную буферизацию, значения, извлекаемые методами get<Type>Stream, могут быть извлечены только один раз. Если выполняется попытка вызвать какой-либо метод get<Type> для того же столбца или параметра после вызова метода get<Type>Stream того же объекта, возникает исключение с сообщением: "Доступ к данным уже был осуществлен, данные недоступны для этого столбца или параметра".
Примечание.
Вызов ResultSet.close() в процессе обработки ResultSet потребует, чтобы драйвер Microsoft JDBC для SQL Server считал и отбросил все оставшиеся пакеты. Это может занять значительное время, если запрос возвращает большой набор данных, особенно в случае, если сетевое подключение слишком медленное.
Руководство по использованию адаптивной буферизации
Разработчики должны следовать данному руководству для минимизации использования памяти приложением.
Старайтесь не использовать свойство строки подключения selectMethod=cursor, позволяющее приложению обрабатывать результирующий набор очень большого объема. Функция адаптивной буферизации позволяет приложениям обрабатывать очень большие однопроходные результирующие наборы, доступные только для чтения, без использования серверного курсора. Обратите внимание, что если задать selectMethod=cursor, это повлияет на все однонаправленные наборы результатов, доступные только для чтения, созданные данным соединением. Другими словами, если приложение рутинно обрабатывает короткие результирующие наборы с несколькими строками, создание, считывание и закрытие серверного курсора для каждого результирующего набора будет использовать больше ресурсов как на стороне клиента, так и на стороне сервера, чем в случае, когда параметру selectMethod не присвоено значение cursor.
Выполняйте считывание больших текстовых или двоичных значений в виде потоков с помощью методов getAsciiStream, getBinaryStream или getCharacterStream вместо методов getBlob или getClob. Начиная с версии 1.2 класс SQLServerCallableStatement предоставляет новые методы get<Type>Stream для этой цели.
Убедитесь в том, что столбцы со значениями потенциально большого объема размещаются последними в списке столбцов в инструкции SELECT и что методы get<Type>Stream класса SQLServerResultSet используются для доступа к столбцам в порядке их выбора.
Убедитесь в том, что параметры OUT со значениями потенциально большого объема объявляются последними в списке параметров в инструкции SQL, используемой для создания SQLServerCallableStatement. Кроме того, убедитесь в том, что методы get<Type>Stream класса SQLServerCallableStatement используются для доступа к параметрам OUT в порядке их объявления.
Старайтесь не выполнять более одной инструкции относительно одного соединения одновременно. Выполнение другой инструкции до обработки результатов предыдущей инструкции может привести к тому, что необработанные результаты будут загружаться в память приложения.
В некоторых случаях использование selectMethod=cursor вместо responseBuffering=adaptive будет более полезным, например:
Если приложение медленно обрабатывает результирующий набор с последовательным доступом и только для чтения, например если каждая строка считывается после какого-либо действия пользователя, использование selectMethod=cursor вместо responseBuffering=adaptive может помочь уменьшить потребление ресурсов SQL Server.
Если приложение одновременно обрабатывает два или более однонаправленных результирующих наборов только для чтения через одно и то же подключение, использование selectMethod=cursor вместо responseBuffering=adaptive может помочь сократить объем памяти, требуемой драйверу для обработки этих результирующих наборов.
В обоих случаях необходимо учитывать чрезмерное потребление ресурсов при создании, считывании и закрытии серверных курсоров.
Кроме того, в следующем списке приводится несколько рекомендаций по работе с прокручиваемыми и однопроходными обновляемыми наборами результатов.
Для прокручиваемых результирующих наборов при возвращении блока строк драйвер всегда считывает число строк, указанных методом getFetchSize объекта SQLServerResultSet, даже если включена адаптивная буферизация. Если прокручивание вызывает ошибку OutOfMemoryError, можно уменьшить число строк, возвращаемых при вызове метода setFetchSize объекта SQLServerResultSet, чтобы задать в качестве размера выборки меньшее число строк. При необходимости можно даже задать 1 строку. Если это не позволяет устранить ошибку OutOfMemoryError, старайтесь не включать столбцы очень большого объема в прокручиваемые результирующие наборы.
Для однопроходных обновляемых результирующих наборов при возвращении блока строк драйвер обычно считывает в память число строк, указанное методом getFetchSize объекта SQLServerResultSet, даже если для подключения включена адаптивная буферизация. Если вызов метода next объекта SQLServerResultSet приводит к ошибке OutOfMemoryError, можно уменьшить число возвращаемых строк, вызвав метод setFetchSize объекта SQLServerResultSet, чтобы задать в качестве размера выборки меньшее число строк. При необходимости можно даже задать 1 строку. Можно также принудительно запретить драйверу буферизовать какие-либо строки, вызвав метод setResponseBuffering объекта SQLServerStatement с параметром "adaptive" перед выполнением инструкции. Так как результирующий набор не является прокручиваемым, если приложение получает доступ к значению столбца большого объема при помощи одного из методов get<Type>Stream, драйвер отбрасывает значение, как только приложение его считывает, так же как это происходит в случае с однопроходными результирующими наборами только для чтения.