• No results found

Reading ability and phonological awareness

Una nueva característica de JDBC 2.0 es el soporte de actualización por lotes. Esta característica permite pasar las actualizaciones de la base de datos como una sola transacción entre el programa de usuario y la base de datos. Este procedimiento puede mejorar significativamente el rendimiento cuando deben realizarse muchas actualizaciones simultáneamente. Por ejemplo, si una empresa grande necesita que sus nuevos empleados empiecen a trabajar un Lunes, este requisito hace necesario procesar muchas actualizaciones (en este caso, inserciones) en la base de datos de empleados simultáneamente. Creando un lote de actualizaciones y sometiéndolas a la base de datos como una unidad, puede ahorrar tiempo de proceso.

Existen dos tipos de actualizaciones por lotes:

v Actualizaciones por lotes que utilizan objetos Statement.

v Actualizaciones por lotes que utilizan objetos PreparedStatement.

Para utilizar el soporte de actualización por lotes, consulte la sección:

Actualización por lotes de Statement

Antes de realizar una actualización por lotes de tipo statement, debe asegurarse de que el

compromiso automático está desactivado. Si el valor de compromiso automático está desactivado, puede crear un objeto Statement estándar. A continuación, puede añadir las sentencias al lote con el método addBatch.Una vez añadidas todas las sentencias que desea al lote, puede procesarlas todas con el método executeBatch o vaciar el lote en cualquier momento con el método clearBatch.

Actualización por lotes de PreparedStatement

Un lote preparedStatement es parecido al lote Statement. Sin embargo, un lote preparedStatement funciona siempre sobre la misma sentencia preparada, y el usuario sólo cambia los parámetros de esa sentencia.

BatchUpdateException

Cuando falla una llamada al método executeBatch, se lanza una BatchUpdateException.

BatchUpdateException permite llamar a los mismos métodos a los que ha llamado siempre para recibir el mensaje, SQLState y el código del proveedor. BatchUpdateException también proporciona el método getUpdateCounts, que devuelve una matriz de enteros. La matriz de enteros contiene cuentas de actualización de todas las sentencias del lote que se han procesado hasta el punto en el que se ha producido la anomalía.

Soporte de inserción por bloques

La inserción por bloques es una operación iSeries para insertar varias filas en una tabla de base de datos simultáneamente.

Actualización por lotes de Statement:

Para realizar una actualización por lotes de Statement, debe desactivar el compromiso automático. En Java Database Connectivity (JDBC), el compromiso automático está activado por omisión. El compromiso automático significa que las actualizaciones de la base de datos se comprometen después de procesar cada sentencia SQL. Si desea tratar un grupo de sentencias que se manejan en la base de datos como un grupo funcional, no deseará que la base de datos comprometa cada sentencia individualmente. Si no desactiva el compromiso automático y falla una sentencia situada en medio del lote, no podrá retrotraer la totalidad del lote e intentarlo de nuevo, ya que la mitad de las sentencias se han convertido en finales. Además, el trabajo adicional de comprometer cada sentencia de un lote crea una gran cantidad de carga de trabajo. Consulte la sección Transacciones para obtener más detalles.

Después de desactivar el compromiso automático, puede crear un objeto Statement estándar. En lugar de procesar sentencias con métodos como por ejemplo executeUpdate, se añaden al lote con el método addBatch. Una vez añadidas todas las sentencias que desea al lote, puede procesarlas todas con el método executeBatch. Puede vaciar el lote en cualquier momento con el método clearBatch.

El ejemplo siguiente muestra cómo puede utilizar estos métodos:

Ejemplo: actualización por lotes de Statement

Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.

connection.setAutoCommit(false);

Statement statement = connection.createStatement();

statement.addBatch(“INSERT INTO TABLEX VALUES(1, ’Cujo’)”); statement.addBatch(“INSERT INTO TABLEX VALUES(2, ’Fred’)”); statement.addBatch(“INSERT INTO TABLEX VALUES(3, ’Mark’)”); int [] counts = statement.executeBatch();

connection.commit();

En este ejemplo, se devuelve una matriz de enteros desde el método executeBatch. Esta matriz tiene un valor entero para cada sentencia que se procesa en el lote. Si se insertan valores en la base de datos, el valor de cada sentencia es 1 (suponiendo que el proceso sea satisfactorio). Sin embargo, algunas de las sentencias pueden ser sentencias de actualización (update) que afectan a varias filas. Si coloca en el lote sentencias que no son INSERT, UPDATE o DELETE, se produce una excepción.

Actualización por lotes de PreparedStatement:

Un lote preparedStatement es parecido al lote Statement; sin embargo, un lote preparedStatement funciona siempre sobre la misma sentencia″preparada″, y el usuario sólo cambia los parámetros para dicha sentencia. A continuación se ofrece un ejemplo que utiliza un lote preparedStatement.

Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.

connection.setAutoCommit(false); PreparedStatement statement =

connection.prepareStatement(“INSERT INTO TABLEX VALUES(?, ?)”); statement.setInt(1, 1); statement.setString(2, “Cujo”); statement.addBatch(); statement.setInt(1, 2); statement.setString(2, “Fred”); statement.addBatch(); statement.setInt(1, 3); statement.setString(2, “Mark”); statement.addBatch();

int [] counts = statement.executeBatch(); connection.commit();

BatchUpdateException:

Una consideración importante acerca de las actualizaciones por lotes es la acción que debe realizarse cuando falla una llamada al método executeBatch. En este caso, se lanza un nuevo tipo de excepción, denominada BatchUpdateException. BatchUpdateException es una subclase de SQLException que permite llamar a los mismos métodos a los que ha llamado siempre para recibir el mensaje, SQLState y el código del proveedor. BatchUpdateException también proporciona el método getUpdateCounts, que devuelve una matriz de enteros. La matriz de enteros contiene cuentas de actualización de todas las sentencias del lote que se han procesado hasta el punto en el que se ha producido la anomalía. La longitud de la matriz indica qué sentencia del lote ha fallado. Por ejemplo, si la matriz devuelta en la excepción tiene una longitud de tres, la cuarta sentencia del lote ha fallado. Por tanto, a partir del único objeto BatchUpdateException devuelto puede determinar las cuentas de actualización para todas las sentencias que han sido satisfactorias, qué sentencia ha fallado y toda la información acerca de la anomalía.

Actualmente, el rendimiento estándar del proceso de actualizaciones por lotes es equivalente al

rendimiento del proceso de cada sentencia por separado. Puede consultar la sección Soporte de inserción por bloques para obtener más información acerca del soporte optimizado para actualizaciones por lotes. Debe seguir utilizando el nuevo modelo al codificar y sacar provecho de futuras optimizaciones del rendimiento.

Nota: En la especificación JDBC 2.1, se suministra una opción diferente para el manejo de condiciones de excepción para actualizaciones por lotes. JDBC 2.1 presenta un modelo en el que el proceso por lotes continúa después de que falle una entrada del lote. Se sitúa una cuenta de actualización especial en la matriz de enteros de cuenta de actualización que se devuelve por cada entrada que falla. Esto permite que lotes de gran tamaño se continúen procesando aunque falle una de sus entradas. Consulte la especificación JDBC 2.1 o JDBC 3.0 para obtener detalles acerca de estas dos modalidades de operación. Por omisión, el controlador JDBC nativo utiliza la definición de JDBC 2.0. El controlador proporciona una propiedad Connection que se utiliza al utilizar DriverManager para establecer las conexiones. También proporciona una propiedad DataSource que se utiliza al utilizar DataSources para establecer las conexiones. Estas propiedades permiten a las aplicaciones elegir cómo desean que las operaciones por lotes manejen las anomalías.

Soporte de inserción por bloques:

Una inserción por bloques es un tipo especial de operación en un servidor iSeries que proporciona una forma altamente optimizada de insertar varias filas en una tabla de base de datos simultáneamente. Las inserciones por bloques pueden considerarse como un subconjunto de actualizaciones por lotes. Las actualizaciones por lotes pueden ser cualquier forma de petición de actualización, pero las inserciones por bloques son específicas. Sin embargo, los tipos de inserción por bloques de actualizaciones por lotes son comunes; el controlador JDBC nativo se ha modificado para sacar partido de esta característica.

Debido a las restricciones del sistema al utilizar el soporte de inserción por bloques, el valor por omisión para el controlador JDBC nativo es tener la inserción por bloques inhabilitada. Puede habilitarse mediante una propiedad Connection de una propiedad DataSource. La mayoría de las restricciones de utilización de una inserción por bloques pueden comprobarse y manejarse en nombre del usuario, pero no así algunas restricciones; esta es la razón por la que el soporte de inserción por bloques esté desactivado por omisión. La lista de restricciones es la siguiente:

v La sentencia SQL utilizada debe ser una sentencia INSERT con una cláusula VALUES, indicando que no es una sentencia INSERT con SUBSELECT. El controlador JDBC reconoce esta restricción y realiza las acciones adecuadas.

v Debe utilizarse una PreparedStatement, indicando que no existe soporte optimizado para objetos

Statement. El controlador JDBC reconoce esta restricción y realiza las acciones adecuadas.

v La sentencia SQL debe especificar marcadores de parámetro para todas las columnas de la tabla. Esto significa que no puede utilizar valores de constante para una columna ni permitir que la base de datos inserte valores por omisión para ninguna de las columnas. El controlador JDBC no tiene ningún

mecanismo para manejar las pruebas de marcadores de parámetro específicos en la sentencia SQL. Si establece la propiedad para realizar inserciones por bloques optimizadas y no evita los valores por omisión o constantes en las sentencias SQL, los valores que terminen en la tabla de base de datos no serán correctos.

v La conexión debe establecerse con el sistema local. Esto significa que no puede utilizarse una conexión que utilice DRDA para acceder a un sistema remoto, debido a que DRDA no soporta una operación de inserción por bloques. El controlador JDBC no tiene ningún mecanismo para manejar las pruebas de una conexión con un sistema local. Si establece la propiedad para realizar una inserción por bloques optimizada e intenta conectarse con un sistema remoto, el proceso de la actualización por lotes fallará.

Este ejemplo de código muestra cómo habilitar el soporte para el proceso de inserción por bloques. La única diferencia entre este código y una versión que no utilizara el soporte de inserción por bloques es

use block insert=true, que se añade al URL de conexión. Ejemplo: Proceso de inserción por bloques

Nota: lea el apartado Declaración de limitación de responsabilidad sobre el código de ejemplo para obtener información legal importante.

// Crear una conexión de base de datos

Connection c = DriverManager.getConnection(“jdbc:db2:*local;use block insert=true”); BigDecimal bd = new BigDecimal(“123456”);

// Crear una PreparedStatement para insertarla en una tabla con 4 columnas PreparedStatement ps =

c.prepareStatement(“insert into cujosql.xxx values(?, ?, ?, ?)”); // Iniciar temporización...

for (int i = 1; i <= 10000; i++) {

ps.setInt(1, i); // Establecer todos los parámetros para una fila ps.setBigDecimal(2, bd);

ps.setBigDecimal(3, bd); ps.setBigDecimal(4, bd);

ps.addBatch(); // Añadir los parámetros al proceso por lotes }

// Procesar los lotes

int[] counts = ps.executeBatch(); // Finalizar temporización...

En pruebas similares, una inserción por bloques es varias veces más rápida que realizar las mismas operaciones sin utilizar una inserción por bloques. Por ejemplo, la prueba realizada en el código anterior es nueve veces más rápida con la utilización de inserciones por bloques. En los casos en que sólo se utilizan tipos nativos en lugar de objetos, la velocidad puede ser hasta dieciséis veces mayor. En las aplicaciones en las que existe una cantidad significativa de trabajo en ejecución, las expectativas deben modificarse adecuadamente.