2012-05-03 11 views
7

Situazione
Ho un'applicazione Web (Tomcat) Java che utilizza jTDS per connettersi a un database MSSQL 2008. Questa applicazione Java esegue il 99% delle sue stored procedure MSSQL utilizzando l'input dell'utente.jTDS + stored procedure + prepareSQL = errore del livello di annidamento?

Problema
Il driver jTDS risponde a volte (a diversi posti nella domanda) con l'errore:

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

Possiamo evitare questo aggiungendo prepareSQL=0 alla stringa di connessione jTDS. Quindi l'errore scompare ovunque, ma con tutti gli altri valori di prepareSQL, l'errore rimane. Non so quanti livelli di nesting delle stored procedure aggiungono jTDS, ma a quanto pare è troppo per la nostra applicazione.

Domande

  1. Con solo stored procedure per eseguire, ovviamente utilizzando prepared statement nel codice Java, quanto effetto fa prepareSQL=3 (o prepareSQL=0) hanno per noi? In altre parole: su tutti i siti Web trovo che le persone dicono "Non usare mai prepareSQL=0 negli ambienti di produzione", è applicabile anche a questa situazione?

  2. Se prepareSQL=0 non è una soluzione consigliata, un problema di sicurezza, ecc., Dovremmo forse cercare un altro driver. jTDS non è stato aggiornato negli ultimi 2 anni e Microsoft ha un driver per JDBC 4.0. Non riesco però a trovare benchmark o confronti tra jTDS e il driver JDBC 4.0 di Microsoft. Con i driver Microsoft 2.0 e 3.0, l'opinione generale sembrava essere che jTDS fosse più veloce, migliore, più efficiente. È ancora così con JDBC 4.0 o Microsoft ha superato il suo concorrente in questo?

+0

Sei riuscito a individuare questo comportamento in una procedura specifica o sembra casuale? – heikkim

+0

No, non abbiamo (ancora). Abbiamo visto questo errore in due diverse implementazioni della nostra applicazione in due diversi punti dell'applicazione, ma quando si è verificato, è stato testardo e potrebbe essere risolto solo utilizzando la soluzione prepareSQL = 0. – bartlaarhoven

risposta

2

quando prepareSQL non è uguale a 0 jTDS aggiungere esattamente livello uno sulla nidificazione. Considerare seguire la procedura:

CREATE PROCEDURE F @v int 
AS 
BEGIN 
    select @v = @v - 1 
    IF @v = 0 SELECT @v 
    ELSE EXEC F @v 
END 

e il codice Java che lo utilizzano:

Connection connection = DriverManager.getConnection("jdbc:jtds:sqlserver://xxx.xxx.xxx.xxx:1433/xxx;prepareSQL=0"); 
PreparedStatement statement = connection.prepareStatement("EXEC F ?"); 
statement.setInt(1, 32); 
statement.execute(); 

Se si imposta prepareSQL di valore diverso da 0 fallirà con "Massimo stored procedure, funzioni, trigger e viste nidificazione livello superato (limite 32) ". Hai bisogno di trovare il motivo per cui il tuo codice usa così tanto annidamento? PreparSQL = 0 stai impedendo a mssql di usare gli stame e quelli che costringono ad analizzare SQL su ogni esecuzione. Non è un grosso problema se il tempo di esecuzione dell'istruzione è molto più quel tempo di compilazione delle istruzioni (E.G. se procedyre memorizzato esegue 10 secondi, non è un problema se la compilazione richiede 10ms in più). Cambiare driver non ti aiuterà perché avrai gli stessi problemi.

Problemi correlati