적응 버퍼링 사용
적응 버퍼링은 서버 커서의 오버헤드 없이 모든 종류의 큰 값 데이터를 검색하도록 설계되었습니다. 응용 프로그램은 드라이버에서 지원하는 모든 버전의 SQL Server에서 적응 버퍼링 기능을 사용할 수 있습니다.
일반적으로 Microsoft JDBC Driver for SQL Server에서 쿼리를 실행하면 드라이버는 서버의 모든 결과를 응용 프로그램 메모리로 검색합니다. 이 방법은 SQL Server에서의 리소스 사용을 최소화하지만, 매우 큰 결과를 생성하는 쿼리일 경우 JDBC 응용 프로그램에서 OutOfMemoryError가 발생할 수도 있습니다.
Microsoft JDBC Driver for SQL Server는 응용 프로그램에서 매우 큰 결과를 처리할 수 있도록 적응 버퍼링을 제공합니다. 선택 버퍼링을 사용하면 드라이버는 SQL Server에서 명령문 실행 결과를 한 번에 모두 검색하는 것이 아니라 응용 프로그램에 필요할 때 검색합니다. 또한 애플리케이션에서 더 이상 액세스할 수 없는 결과를 즉시 삭제합니다. 다음은 선택 버퍼링을 유용하게 사용할 수 있는 몇 가지 예입니다.
쿼리는 매우 큰 결과 집합을 생성합니다. 응용 프로그램 메모리에 저장할 수 있는 것보다 많은 행을 생성하는 SELECT 문을 응용 프로그램에서 실행할 수 있습니다. 이전 릴리스에서 응용 프로그램은 OutOfMemoryError를 방지하기 위해 서버 커서를 사용해야 했습니다. 적응 버퍼링은 서버 커서 없이도 임의적으로 큰 결과 집합의 정방향 읽기 전용 전달을 수행하는 기능을 제공합니다.
쿼리는 매우 큰 SQLServerResultSet 열 또는 SQLServerCallableStatement OUT 매개 변수 값을 생성합니다. 응용 프로그램 메모리 전체에 해당할 만큼 너무 큰 단일 값(열 또는 OUT 매개 변수)을 응용 프로그램에서 검색할 수 있습니다. 적응 버퍼링을 사용하면 클라이언트 애플리케이션에서 getAsciiStream, getBinaryStream 또는 getCharacterStream 메서드를 사용하여 이러한 값을 스트림으로 검색할 수 있습니다. 응용 프로그램은 스트림에서 읽으면서 SQL Server에서 해당 값을 검색합니다.
참고 항목
선택 버퍼링을 사용하면 JDBC 드라이버는 필요한 양의 데이터만 버퍼링합니다. 드라이버는 버퍼 크기를 제어 또는 제한하는 공용 메서드를 제공하지 않습니다.
적응 버퍼링 설정
JDBC 드라이버 버전 2.0부터 드라이버의 기본 동작은 "적응"입니다. 즉, 적응 버퍼링 동작을 얻기 위해 응용 프로그램에서 명시적으로 적응 동작을 요청할 필요가 없습니다. 하지만 버전 1.2 릴리스에서 버퍼링 모드는 기본적으로 "전체"이며 응용 프로그램에서는 적응 버퍼링 모드를 명시적으로 설정해야 합니다.
응용 프로그램에서 문 실행을 요청할 수 있는 세 가지 방법은 적응 버퍼링을 사용해야 합니다.
응용 프로그램에서는 responseBuffering 연결 속성을 "적응"으로 설정할 수 있습니다. 연결 속성을 설정하는 방법에 대한 자세한 내용은 연결 속성 설정을 참조하세요.
응용 프로그램에서는 SQLServerDataSource 개체의 setResponseBuffering 메서드를 사용하여 SQLServerDataSource 개체를 통한 모든 연결에 대한 응답 버퍼링 모드를 설정할 수 있습니다.
애플리케이션에서 SQLServerStatement 클래스의 setResponseBuffering 메서드를 사용하여 특정 문 개체에 대해 응답 버퍼링 모드를 설정할 수 있습니다.
JDBC 드라이버 버전 1.2를 사용하는 경우 응용 프로그램에서 setResponseBuffering 메서드를 사용하려면 문 개체를 SQLServerStatement 클래스로 캐스팅해야 했습니다. 대용량 데이터 읽기 샘플 및 저장 프로시저를 사용하여 큰 데이터 읽기 샘플의 코드 예제 에서는 이전의 사용 방식을 보여 줍니다.
그러나 JDBC 드라이버 버전 2.0에서 응용 프로그램은 isWrapperFor 메서드 및 unwrap 메서드를 사용하여 구현 클래스 계층 구조형을 가정하지 않고도 공급업체별 기능에 액세스할 수 있습니다. 예제 코드는 큰 데이터 업데이트 샘플을 참조하세요.
적응 버퍼링을 사용하여 큰 데이터 검색
get<Type>Stream 메서드를 사용하여 큰 값을 한 번 읽은 다음, SQL Server에서 반환하는 순서로 ResultSet 열과 CallableStatement 출력 매개 변수에 액세스하면 결과를 처리할 때 선택 버퍼링이 애플리케이션 메모리 사용량을 최소화합니다. 적응 버퍼링 사용 시기:
SQLServerResultSet 및 SQLServerCallableStatement 클래스에 정의된 get<Type>Stream 메서드는 애플리케이션에서 표시하는 경우 스트림을 재설정할 수 있다 하더라도 기본적으로 한 번 읽기 스트림을 반환합니다. 응용 프로그램에서 스트림
reset
을 원하는 경우, 먼저 스트림에서mark
메서드를 호출해야 합니다.SQLServerClob 및 SQLServerBlob 클래스에 정의된 get<Type>Stream 메서드는
mark
메서드를 호출하지 않고 항상 스트림의 시작 위치로 변경될 수 있는 스트림을 반환합니다.
애플리케이션에서 선택 버퍼링을 사용하는 경우 get<Type>Stream 메서드에 의해 검색된 값은 한 번만 검색될 수 있습니다. 같은 개체의 get<Type>Stream 메서드를 호출한 후 같은 열이나 매개 변수에서 get<Type> 메서드를 호출하려고 하면 “데이터에 액세스되었으나 이 열이나 매개 변수에는 사용할 수 없습니다.”라는 메시지와 함께 예외가 발생합니다.
참고 항목
ResultSet을 처리하는 동안 ResultSet.close()를 호출하려면 Microsoft JDBC Driver for SQL Server가 남은 패킷 모두를 읽고 무시해야 합니다. 쿼리로 큰 데이터 집합이 반환되고 특히 네트워크 연결 속도가 느리다면 이 작업에 상당한 시간이 걸릴 수 있습니다.
적응 버퍼링 사용 지침
응용 프로그램 메모리 사용량을 최소화하려는 개발자는 다음의 중요한 지침을 따라야 합니다.
애플리케이션에서 매우 큰 결과 집합을 처리할 수 있도록 연결 문자열 속성 selectMethod=cursor를 사용하지 않도록 합니다. 적응 버퍼링 기능을 사용하면 응용 프로그램에서 서버 커서를 사용하지 않고도 매우 큰 정방향 읽기 전용 결과 집합을 처리할 수 있습니다. selectMethod=cursor로 설정하면 연결로 생성된 모든 정방향 읽기 전용 결과 집합이 영향을 받습니다. 즉, 응용 프로그램에서 몇 개의 행으로 짧은 결과 집합을 정기적으로 처리하는 경우에는 각 결과 집합에 대한 서버 커서를 만들고, 읽고, 닫을 때 selectMethod가 cursor로 설정되지 않은 경우보다 클라이언트 쪽 및 서버 쪽 모두에서 더 많은 리소스를 사용하게 됩니다.
getBlob 또는 getClob 메서드 대신 getAsciiStream, getBinaryStream 또는 getCharacterStream 메서드를 사용하여 큰 텍스트 또는 이진 값을 스트림으로 읽습니다. 버전 1.2 릴리스부터 이 용도를 위해 SQLServerCallableStatement 클래스는 새로운 get<Type>Stream 메서드를 제공합니다.
SELECT 문에서 잠재적으로 큰 값을 갖는 열이 열 목록의 마지막에 배치되도록 하고 SQLServerResultSet의 get<Type>Stream 메서드를 사용하여 해당 메서드가 선택된 순서로 해당 열에 액세스하도록 합니다.
큰 값을 가질 수 있는 OUT 매개 변수가 SQLServerCallableStatement를 만드는 데 사용되는 SQL의 매개 변수 목록에서 마지막으로 선언되었는지 확인합니다. 또한 SQLServerCallableStatement의 get<Type>Stream 메서드를 사용하여 해당 메서드가 선언된 순서로 출력 매개 변수에 액세스하도록 합니다.
동일한 연결에서 둘 이상의 문을 동시에 실행하지 않도록 합니다. 이전 문의 결과를 처리하기 전에 다른 문을 실행하면 처리되지 않은 결과가 응용 프로그램 메모리에 버퍼링될 수 있습니다.
다음과 같이, responseBuffering=adaptive 대신 selectMethod=cursor를 사용하는 것이 더 유익한 경우가 있습니다.
응용 프로그램에서 사용자 입력을 받은 후 각 행을 읽는 등 정방향 읽기 전용 결과 집합을 천천히 처리하는 경우 responseBuffering=adaptive 대신 selectMethod=cursor를 사용하면 SQL Server의 리소스 사용량을 줄일 수 있습니다.
응용 프로그램이 동일한 연결에서 정방향 읽기 전용 결과 집합을 동시에 두 개 이상 처리하는 경우, responseBuffering=adaptive 대신 selectMethod=cursor를 사용하면 이러한 결과 집합을 처리하는 동안 드라이버에 필요한 메모리를 줄일 수 있습니다.
두 경우 모두 서버 커서를 만들고 읽고 닫는 오버헤드를 고려해야 합니다.
또한 다음 목록에서는 스크롤할 수 있고 업데이트 가능한 정방향 결과 집합에 대한 몇 가지 권장 사항을 제공합니다.
스크롤 가능한 결과 집합의 경우, 행 블록을 페치할 때 드라이버는 적응 버퍼링을 사용하는 경우에도 SQLServerResultSet 개체의 getFetchSize 메서드에서 나타내는 행 수를 항상 메모리로 읽습니다. 스크롤로 인해 OutOfMemoryError가 발생한다면, SQLServerResultSet 개체의 setFetchSize 메서드를 호출하여 페치 크기를 더 작은 수의 행으로, 필요하다면 1행까지 줄이도록 설정하여 페치된 행 수를 줄일 수 있습니다. 이렇게 해도 OutOfMemoryError가 발생하는 경우에는 스크롤 가능한 결과 집합에 아주 큰 열을 포함하지 마십시오.
업데이트 가능한 정방향 결과 집합의 경우, 행 블록을 페치할 때 드라이버는 연결에 적응 버퍼링을 사용하는 경우에도 SQLServerResultSet 개체의 getFetchSize 메서드에서 나타내는 행 수를 보통 메모리로 읽습니다. SQLServerResultSet 개체의 next 메서드 호출로 인해 OutOfMemoryError가 발생한다면, SQLServerResultSet 개체의 setFetchSize 메서드를 호출하여 페치 크기를 더 작은 수의 행으로, 필요하다면 1행까지 줄이도록 설정하여 페치된 행 수를 줄일 수 있습니다. 문을 실행하기 전에 "adaptive" 매개 변수를 사용하여 SQLServerStatement 개체의 setResponseBuffering 메서드를 호출하여 드라이버가 행을 버퍼링하지 않도록 강제할 수도 있습니다. 결과 집합을 스크롤할 수 없으므로 애플리케이션이 get<Type>Stream 메서드 중 하나를 사용하여 큰 열 값에 액세스하는 경우 드라이버는 정방향 읽기 전용 결과 집합을 처리할 때와 마찬가지로 애플리케이션이 값을 읽는 즉시 해당 값을 삭제합니다.