java - supero - transacciones anidadas sql server ejemplos
jTDS+procedimientos almacenados+prepareSQL=error de nivel de anidamiento? (1)
Situación
Tengo una aplicación web Java (Tomcat) que utiliza jTDS para conectarme a una base de datos MSSQL 2008. Esta aplicación Java ejecuta el 99% de sus procedimientos almacenados MSSQL utilizando la entrada del usuario.
Problema
El controlador jTDS responde a veces (en diferentes lugares de la aplicación) con un error:
Se superó el nivel máximo de procedimiento almacenado, función, disparador o vista anidado (límite 32).
Podemos evitar esto agregando prepareSQL=0
a la cadena de conexión jTDS. Entonces el error desaparece en todas partes, pero con todos los demás valores de prepareSQL
, el error permanece. No sé cuántos niveles de anidación de procedimientos almacenados jTDS agrega, pero aparentemente es demasiado para nuestra aplicación.
Preguntas
Con solo procedimientos almacenados para ejecutar, por supuesto, usando Declaraciones preparadas en el código Java, ¿cuánto efecto tiene
prepareSQL=3
(oprepareSQL=0
) para nosotros? En otras palabras: en cada sitio web encuentro personas que dicen "Nunca usesprepareSQL=0
en entornos de producción", ¿eso también es aplicable a esta situación?Si
prepareSQL=0
no es una solución recomendada, un problema de seguridad, etc., deberíamos buscar otro controlador. jTDS no se ha actualizado en los últimos 2 años y Microsoft tiene un controlador para JDBC 4.0. Sin embargo, no puedo encontrar referencias ni comparaciones entre jTDS y el controlador JDBC 4.0 de Microsoft. Con los controladores 2.0 y 3.0 de Microsoft, la opinión general parecía ser que jTDS es más rápido, mejor y más eficiente. ¿Sigue siendo así con JDBC 4.0 o Microsoft ha superado a su competidor en esto?
cuando prepareSQL no es igual a 0 jTDS, agregue exactamente un nivel en la anidación. Considere seguir el procedimiento:
CREATE PROCEDURE F @v int
AS
BEGIN
select @v = @v - 1
IF @v = 0 SELECT @v
ELSE EXEC F @v
END
Y código java que lo usa:
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();
Si configura prepareSQL a un valor distinto de 0 fallará con "Máximo procedimiento almacenado, función, desencadenante o nivel de anidación de la vista excedido (límite 32)". ¿Necesitas encontrar por qué tu código usa tanta anidación? Por prepareSQL = 0 está impidiendo que mssql use stamements y forzar a analizar SQL en cada ejecución. No es un gran problema si el tiempo de ejecución de la instrucción es mucho más que el tiempo de compilación de la declaración (por ejemplo, si el procedimiento almacenado se ejecuta 10 segundos, no es un problema si la compilación tomó 10 ms más). Cambiar el controlador no ayudará porque tendrá los mismos problemas.