prepared - statement java parameters
¿Por qué establecer Autocommit en true? (7)
Me he preguntado durante mucho tiempo por qué la API de JDBC proporciona un modo de confirmación automática ( java.sql.Connection.setAutocommit()
). Parece una molestia atractiva que solo atrae a la gente a problemas. Mi teoría es que solo se agregó a JDBC para simplificar la vida de los proveedores que querían crear herramientas para editar y ejecutar SQL utilizando JDBC. ¿Hay alguna otra razón para activar el compromiso automático o siempre es un error?
Bueno, hay ciertas condiciones que necesitan una mirada cuidadosa al habilitar el "auto-commit" a nivel global:
a.) La gestión de transacciones en el nivel de consulta quedará a criterio del usuario; para una instancia, si se necesita una gran cantidad de consultas para tener éxito o fallar juntas, entonces se debe ajustar en BEGIN y confirmar Transacción.
b.) Recuerde, no hay retroceso cuando está habilitada la "confirmación automática".
c.) También hay una sobrecarga de escribir (cometer) todas y cada una de las transacciones.
d.) Para las consultas de solo lectura no hay necesidad explícita de "autocompromiso", pero habilitando "autocompromiso" se aplica automáticamente para todas las consultas.
Si el bloqueo de la mesa es la única preocupación para habilitar el autocompromiso, entonces puede que no sea una buena idea, más bien se puede recurrir a tiempos de espera de bloqueo más bajos.
Casi siempre corro con autocommit = true. 99% del tiempo, mis actualizaciones son atómicas. Claro, hay casos en los que escribe el débito y luego falla al intentar escribir el crédito que desea revertir. Pero en mi experiencia, estos son relativamente raros. Por lo general, cada registro que escribo se sostiene por sí mismo. En ese caso, no es necesario preocuparse por hacer una confirmación después de cada escritura es conveniente. Guarda una línea de código aquí y allá. Puede ahorrar más que eso si, dada la estructura del programa, significa que no necesito un bloque try / catch adicional o que no necesito pasar un objeto de conexión entre funciones. Ahorra en molestos errores donde alguien olvidó hacer un commit.
La única forma en que veo que podría "atraer a alguien a problemas" es que decide desactivar el autocompromiso y hacer la confirmación o deshacer es demasiado problema, por lo que realiza las actualizaciones que deberían estar dentro de una transacción individual. Entonces todo parece funcionar bien siempre y cuando no pase nada que deba abortar la transacción. Si los escenarios de prueba son inadecuados, podría imaginarse que esto se deslice hacia la producción.
Pero podría decir lo mismo sobre casi cualquier característica de un idioma. Como, supongamos que escribes un programa que procesa números que el 90% del tiempo cabrán en un largo, pero de vez en cuando puede ser más grande. Frente a esta situación, lo correcto es usar BigInteger o crear una nueva clase para manejar los números más grandes. Un programador perezoso puede ser atraído a usar mucho porque normalmente funcionará y otras alternativas son demasiados problemas. ¿Concluiría por lo tanto que Java no debería incluir long (o int) porque alguien podría ser atraído a usarlos cuando no son apropiados?
Si en sus programas, la mayoría de las actualizaciones deben realizarse dentro de un contexto de transacción, desactive la confirmación automática. Su presencia no te hace daño. Está ahí para cuando sea conveniente, pero cuando no lo esté, puede apagarlo.
Commit-mode cambia la forma en que el db mantiene bloqueos.
Es aconsejable desactivar el modo autocompromiso solo durante el modo de transacción. De esta forma, evitará mantener bloqueos de base de datos para varias sentencias, lo que aumenta la probabilidad de conflictos con otros usuarios.
...
Para evitar conflictos durante una transacción, un DBMS usa bloqueos, mecanismos para bloquear el acceso de otros a los datos a los que la transacción está accediendo. (Tenga en cuenta que en el modo autocompromiso, donde cada enunciado es una transacción, los bloqueos se guardan solo para una declaración).
http://download.oracle.com/javase/tutorial/jdbc/basics/transactions.html
Desafortunadamente, el uso de autocommit es específico de la base de datos (como es el comportamiento de la transacción). Creo que si no tienes una estrategia global de transacciones programáticas, la confirmación automática es probablemente mejor que simplemente esperar que todos cierren / cancelen las transacciones correctamente.
Hablando en MySQL, puede dejar autocommit = true activado de forma predeterminada, y se apagará automáticamente cuando COMIENCE una transacción. La única razón para establecer autocommit = false es si desea forzar un error si alguien intenta iniciar una transacción sin un BEGIN.
Para simplificar hoy en una aplicación Java + MySQL típica, ignoraría más o menos la configuración de confirmación automática, usaría un patrón de sesión abierta en perspectiva y lo llamaría bueno.
Desafío fuertemente los bloqueos explícitos de filas RDBMS y en su lugar usar bloqueos optimistas. Hibernate ofrece soporte integrado para bloqueos optimistas, pero es un patrón fácil de adoptar incluso para código enrollado a mano y ofrece un mejor rendimiento.
El 95% de la base de código con la que estoy trabajando ahora involucra actualizaciones únicas donde la confirmación automática es perfectamente razonable. Por lo tanto, estamos predeterminados para eso. Solo lo apaga el tiempo suficiente para hacer las secciones de código que deben ser una transacción, ¡y luego vuelve a activarse automáticamente!
La única razón razonable que puedo ver es deshacerse de la plantilla repetitiva connection.commit()
y connection.rollback()
en transacciones simples de consulta única en aplicaciones pequeñas. JDBC en forma cruda requiere por sí solo una gran repetición. Cada línea menos hace que JDBC sea menos aterrador para los principiantes.
La confirmación automática es conveniente; pero con los cambios a la especificación JDBC 3, se ha vuelto mucho menos útil.
Como las 3 conexiones de JDBC en el modo "autocompromiso" no pueden tener más de una instrucción abierta. Al ejecutar otra instrucción, se cerrará la primera, incluido cualquier ResultSet.
Por lo tanto, el bucle dentro de SELECT y la emisión de UPDATE (o incluso SELECT anidados) tenderá a fallar. Aparentemente es un crimen, ¡realmente querer hacer algo con los resultados de tu SELECT externo!
De todos modos, depende del controlador y la versión específicos ... pero, en general, la especificación JDBC 3 parece imponer este comportamiento inútil. La actualización de los controladores también puede "descubrir" inútilmente este comportamiento.
¿Por qué usar autocompromiso? Originalmente, fue útil y conveniente. Como dicen otras respuestas, JDBC requiere cantidades copiosas de GUFF y HANDLING para llamar correctamente. JDBC no es realmente una API bien diseñada :(
En estos días, sería mejor usar Hibernate o Spring''s JdbcTemplate ... Y si está haciendo servlets / aplicaciones web, coloque su gestión de transacciones (inicio / fin) o sesión de Hibernate (agréguelo a un hilo local) en los límites de la "Solicitud de usuario".
por ejemplo, consigue unir tu conexión / transacción al comienzo de ServletRequest; y devolverlo al final.
Puede usar un javax.servlet.Filter o similar, y vincularlo a un thread-local, crear un helper estático para obtenerlo o requerirlo , etc.