Uso del buffer adattivo

Download scaricare ildriver JDBC

La memorizzazione nel buffer adattiva è progettata per recuperare qualsiasi tipo di dati con valori di grandi dimensioni senza l'overhead dei cursori server. Le applicazioni possono usare il buffering adattivo con tutte le versioni di SQL Server supportate dal driver.

In genere, quando Microsoft JDBC Driver per SQL Server esegue una query, il driver recupera tutti i risultati dal server e li carica nella memoria dell'applicazione. Sebbene questo approccio consenta di ridurre al minimo il consumo delle risorse in SQL Server, è possibile che per le query che producono risultati di dimensioni molto grandi venga generato un errore di tipo OutOfMemoryError nell'applicazione JDBC.

Per consentire alle applicazioni di gestire risultati di dimensioni molto grandi, in Microsoft JDBC Driver per SQL Server è disponibile il buffering adattivo. Grazie al buffering adattivo, il driver può recuperare i risultati dell'esecuzione di istruzioni da SQL Server quando questi sono necessari per l'applicazione e non tutti contemporaneamente. Quando l'applicazione non necessita più di accedere ai dati, questi vengono inoltre eliminati dal driver. Di seguito sono illustrati alcuni esempi di casi in cui il buffer adattivo può rivelarsi utile:

  • La query produce un set di risultati di dimensioni molto grandi: l'applicazione può eseguire un'istruzione SELECT che produce più righe di quante possano essere archiviate in memoria. Nelle versioni precedenti era necessario che l'applicazione usasse un cursore server per evitare un errore di tipo OutOfMemoryError. Il buffer adattivo consente di passare in modalità forward-only di sola lettura un set di risultati anche molto grande senza che sia necessario un cursore server.

  • La query produce valori delle colonne SQLServerResultSet o del parametro OUT di SQLServerCallableStatement di dimensioni molto grandi: l'applicazione può recuperare un singolo valore (colonna o parametro OUT) troppo grande per essere caricato interamente nella memoria dell'applicazione. Il buffering adattivo consente all'applicazione client di recuperare questo valore come flusso usando i metodi getAsciiStream, getBinaryStream o getCharacterStream. L'applicazione recupera il valore da SQL Server leggendolo dal flusso.

Nota

Con il buffer adattivo il driver JDBC memorizza nel buffer solo la quantità di dati necessaria e non fornisce alcun metodo pubblico per controllare o limitare le dimensioni del buffer.

Impostazione del buffer adattivo

A partire dalla versione 2.0 del driver JDBC, il comportamento predefinito del driver è "adattivo". In altre parole, per ottenere il comportamento del buffer adattivo in questa versione, l'applicazione non deve richiederlo in modo esplicito. Nella versione 1.2, tuttavia, la modalità di buffering predefinita è "completa" e l'applicazione deve richiedere la modalità di buffering adattivo in modo esplicito.

Un'applicazione può richiedere l'utilizzo del buffer adattivo nell'esecuzione di un'istruzione in tre modi:

Quando si usa la versione 1.2 del driver JDBC, le applicazioni devono eseguire il cast dell'oggetto istruzione in una classe SQLServerStatement per applicare il metodo setResponseBuffering. Questo tipo di utilizzo è illustrato negli esempi di codice descritti in Esempio di lettura di dati di grandi dimensioni e Esempio di lettura di dati di grandi dimensioni con una stored procedure.

Con la versione 2.0 del driver JDBC, tuttavia, le applicazioni possono usare i metodi isWrapperFor e unwrap per accedere a funzionalità specifiche del fornitore senza presupporre l'implementazione della gerarchia di classi. Per un codice di esempio, vedere l'argomento Esempio di aggiornamento di dati di grandi dimensioni.

Recupero di dati di grandi dimensioni con il buffer adattivo

Quando si usano i metodi get<Type>Stream per leggere una sola volta valori di grandi dimensioni e si esegue l'accesso alle colonne ResultSet e ai parametri OUT CallableStatement nell'ordine restituito da SQL Server, il buffer adattivo consente di ridurre al minimo l'utilizzo della memoria dell'applicazione durante l'elaborazione dei risultati. Quando si utilizza il buffer adattivo, si verifica quanto indicato di seguito:

  • I metodi get<Type>Stream definiti nelle classi SQLServerResultSet e SQLServerCallableStatement restituiscono per impostazione predefinita flussi che possono essere letti una sola volta, sebbene possano essere reimpostati, se contrassegnati dall'applicazione. Per applicare il metodo reset al flusso, l'applicazione deve prima chiamare il metodo mark su tale flusso.

  • I metodi get<Type>Stream definiti nelle classi SQLServerClob e SQLServerBlob restituiscono flussi che possono essere sempre spostati nella posizione iniziale del flusso senza chiamare il metodo mark.

Quando l'applicazione usa il buffer adattivo, i valori recuperati dai metodi get<Type>Stream possono essere recuperati una sola volta. Se si tenta di chiamare qualsiasi metodo get<Type> sulla stessa colonna o sullo stesso parametro dopo avere chiamato il metodo get<Type>Stream dello stesso oggetto, verrà generata un'eccezione con il messaggio "Accesso ai dati eseguito. Dati non disponibili per questa colonna o questo parametro".

Nota

Una chiamata a ResultSet.close() durante l'elaborazione di un oggetto ResultSet implica la lettura e la rimozione di tutti i pacchetti rimanenti da parte di Microsoft JDBC Driver per SQL Server. Questa operazione può richiedere molto tempo se la query ha restituito un set di dati di grandi dimensioni e soprattutto se la connessione di rete è lenta.

Linee guida per l'uso del buffer adattivo

Per ridurre al minimo l'utilizzo della memoria da parte dell'applicazione, gli sviluppatori devono attenersi alle importanti linee guida seguenti:

  • Evitare di usare la proprietà della stringa di connessione selectMethod=cursor per consentire all'applicazione di elaborare un set di risultati di dimensioni molto grandi. La caratteristica di buffer adattivo consente alle applicazioni di elaborare set di risultati forward-only di sola lettura di dimensioni molto grandi senza utilizzare un cursore server. Si noti che l'impostazione di selectMethod=cursor influisce su tutti i set di risultati forward-only di sola lettura prodotti da tale connessione. In altre parole, se l'applicazione elabora regolarmente set di risultati brevi contenenti poche righe, per la creazione, la lettura e la chiusura di un cursore server per ogni set di risultati sia sul lato server che sul lato client verrà usato un maggior numero di risorse rispetto a quando selectMethod non è impostato su cursor.

  • Leggere i valori binari o di testo di grandi dimensioni come flussi usando i metodi getAsciiStream, getBinaryStream o getCharacterStream anziché i metodi getBlob o getClob. A partire dalla versione 1.2, nella classe SQLServerCallableStatement sono disponibili nuovi metodi get<Type>Stream da usare a questo scopo.

  • Assicurarsi che le colonne con valori potenzialmente grandi siano posizionate per ultime nell'elenco di colonne in un'istruzione SELECT e che i metodi get<Type>Stream di SQLServerResultSet vengano usati per accedere alle colonne nell'ordine in cui vengono selezionate.

  • Assicurarsi che i parametri OUT con valori potenzialmente grandi siano dichiarati per ultimi nell'elenco di parametri nel linguaggio SQL usato per creare SQLServerCallableStatement. Assicurarsi anche che i metodi get<Type>Stream di SQLServerCallableStatement vengano usati per accedere ai parametri OUT nell'ordine in cui vengono dichiarati.

  • Evitare di eseguire simultaneamente più di un'istruzione nella stessa connessione. Se viene eseguita un'altra istruzione prima dell'elaborazione dei risultati dell'istruzione precedente, i risultati non elaborati potrebbero venire memorizzati nel buffer della memoria dell'applicazione.

  • Di seguito sono descritti alcuni casi in cui è più conveniente usare selectMethod=cursor anziché responseBuffering=adaptive:

    • Se l'applicazione elabora lentamente un set di risultati forward-only di sola lettura, ad esempio leggendo ogni riga dopo un input utente, l'uso di selectMethod=cursor anziché responseBuffering=adaptive può contribuire a ridurre l'utilizzo di risorse da parte di SQL Server.

    • Se l'applicazione elabora due o più set di risultati forward-only di sola lettura contemporaneamente nella stessa connessione, l'uso di selectMethod=cursor anziché responseBuffering=adaptive può contribuire a ridurre la memoria richiesta dal driver durante l'elaborazione dei set di risultati.

    In entrambi i casi, è opportuno considerare l'overhead generato dalla creazione, dalla lettura e dalla chiusura dei cursori server.

Nel seguente elenco vengono inoltre fornite alcune indicazioni relative ai set di risultati scorrevoli e forward-only aggiornabili.

  • Per i set di risultati scorrevoli, durante il recupero di un blocco di righe, il driver legge sempre in memoria il numero di righe indicate dal metodo getFetchSize dell'oggetto SQLServerResultSet, anche quando il buffering adattivo è abilitato. Se lo scorrimento genera un errore di tipo OutOfMemoryError, è possibile ridurre il numero di righe recuperate chiamando il metodo setFetchSize dell'oggetto SQLServerResultSet per impostare le dimensioni del recupero su un numero minore di righe, anche su una se necessario. Se in tal modo non si previene l'errore di tipo OutOfMemoryError, non includere colonne particolarmente estese nei set di risultati scorrevoli.

  • Per i set di risultati forward-only aggiornabili, durante il recupero di un blocco di righe, il driver legge in genere in memoria il numero di righe indicate dal metodo getFetchSize dell'oggetto SQLServerResultSet, anche quando il buffering adattivo è abilitato per la connessione. Se chiamando il metodo next dell'oggetto SQLServerResultSet viene restituito un errore di tipo OutOfMemoryError, è possibile ridurre il numero di righe recuperate chiamando il metodo setFetchSize dell'oggetto SQLServerResultSet per impostare le dimensioni del recupero su un numero minore di righe, anche su una se necessario. È anche possibile forzare il driver a non memorizzare nel buffer alcuna riga chiamando il metodo setResponseBuffering dell'oggetto SQLServerStatement con il parametro "adaptive" prima di eseguire l'istruzione. Poiché il set di risultati non è scorrevole, se l'applicazione accede a un valore di colonna di grandi dimensioni usando uno dei metodi get<Type>Stream, il driver eliminerà il valore non appena verrà letto dall'applicazione, come avviene per i set di risultati forward-only di sola lettura.

Vedere anche

Uso del driver JDBC per il miglioramento di prestazioni e affidabilità