Excepciones pertenecientes al acceso a datos
Todos los beans CMP (persistencia gestionada por contenedor) de enterprise bean en la especificación EJB (Enterprise JavaBeans) 2.x reciben una excepción EJB estándar cuando falla alguna operación. Las aplicaciones JDBC (Java™ Database Connectivity) reciben una excepción SQL estándar si falla alguna operación JDBC. El producto proporciona excepciones especiales para el adaptador de recursos relacional (RRA), para indicar que la conexión que se está manteniendo actualmente ya no es válida.
- La excepción de tiempo de espera de la conexión indica que la aplicación ha esperado el número de segundos especificado por el valor de tiempo de espera y no ha
recibido una conexión. Esta situación puede darse cuando la agrupación tiene el tamaño máximo y las otras
aplicaciones están utilizando todas las conexiones durante el tiempo de espera. Además, actualmente no hay conexiones en uso que la aplicación pueda compartir, porque las
propiedades de la conexión no coinciden, o porque la conexión está en una transacción
diferente.
Para un origen de datos de la versión 4.0, el objeto ConnectionWaitTimeout genera una excepción cuya instancia se crea a partir de la clase com.ibm.ejs.cm.pool.ConnectionWaitTimeoutException.
Para las fábricas de conexiones J2C (Java 2 Connector), el objeto ConnectionWaitTimeout genera una excepción de recurso de la clase com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException.
Cuando el modelo de detección de anomalías se configura para la correlación de excepciones, las versiones posteriores de los orígenes de datos emite una excepción SQL de la subclase com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException. Cuando el modelo de detección de errores se ha configurado para la comprobación de excepciones, las versiones posteriores de los orígenes de datos emiten una excepción SQL de la clase java.sql.SQLTransientConnectionException con una excepción encadenada de la clase com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException.
- Cuando el modelo de detección de anomalías se configura para la correlación de excepciones, la excepción de conexión caducada indica que la conexión ya no es válida. Cuando el modelo de detección de anomalías se configura para la comprobación de excepciones, el controlador JDBC emite una excepción JDBC 4.0, como por ejemplo java.sql.SQLRecoverableException o java.sql.SQLNonTransientConnectionException, o bien especifica un SQLState adecuado para indicar que la conexión ya no es válida. Para obtener más información sobre este tipo de excepción, consulte el tema Conexiones caducadas.
- Las entradas están delimitadas por un ; (punto y coma).
- Cada entrada consta de una clave y un valor, donde la clave es un código de error (valor numérico) o SQLState, que es texto entrecomillado.
- Las claves y los valores están separados por = (signo igual).
"S1000"=;1062=com.ibm.websphere.ce.cm.DuplicateKeyException;"08004"=
com.ibm.websphere.ce.cm.StaleConnectionException
userDefinedErrorMap se puede encontrar en la consola de administración seleccionando el origen de datos y configurando las propiedades personalizadas.- Conexiones caducadas
- Ejemplo: manejo de la excepción de acceso a datos: conexión inactiva
- Conexión en punto muerto en sistemas Linux
- Ejemplo: manejo de las excepciones de conexiones JDBC del servlet
- Ejemplo: manejo de excepciones de conexión para beans de sesión en transacciones de base de datos gestionadas por contenedor
- Ejemplo: manejo de excepciones de conexión para beans de sesión en transacciones de base de datos gestionadas por beans
- Ejemplo: manejo de excepciones de conexión para beans BMP en transacciones de base de datos gestionadas por contenedor
- Ejemplo: manejo de la excepción de acceso a datos - ConnectionWaitTimeoutException (para la API JDBC)
- Ejemplo: manejo de la excepción de acceso a datos - ConnectionWaitTimeoutException (para la arquitectura de conector de Java EE (Java EE Connector Architecture))
- Ejemplo: manejo de la excepción de acceso a datos - error de correlación en DataStoreHelper
- Conflictos entre claves foráneas y bloqueos de base de daos
Conexiones caducadas
El producto proporciona una subclase especial de la clase java.sql.SQLException para utilizar la agrupación de conexiones para acceder a una base de datos relacional. Esta subclase com.ibm.websphere.ce.cm.StaleConnectionException existe en el origen de datos de WebSphere 4.0 y en la versión más reciente del origen de datos que utiliza el adaptador de recursos relacional. Esta clase se utiliza para indicar que la conexión que se mantiene actualmente ya no es válida.
- La aplicación intenta obtener una conexión y no lo consigue, del mismo modo que cuando la base de datos no está iniciada.
- Una conexión ya no se puede utilizar más debido a una anomalía de la base de datos. Cuando una aplicación intenta utilizar una conexión obtenida anteriormente, la conexión ya no es válida. En este caso, es posible que todas las conexiones que la aplicación utiliza actualmente obtengan esta excepción.
- La conexión se ha quedado huérfana (porque la aplicación no la ha utilizado como máximo durante un período de tiempo que duplica el intervalo de tiempo de espera de conexión no utilizada) y la aplicación intenta utilizar la conexión huérfana. Este caso sólo se aplica a los orígenes de datos de la versión 4.0.
- La aplicación intenta utilizar un recurso JDBC, como una sentencia, que ha obtenido de una conexión en punto muerto.
- La característica de limpieza automática de conexiones del origen de
datos de la versión 4.0 ha cerrado la conexión y ya no se puede utilizar. La limpieza automática de conexiones es la modalidad estándar en la que funciona la gestión de conexiones. Esta modalidad indica que cuando
finaliza la transacción, el gestor de transacciones cierra todas las conexiones incluidas en
dicha transacción. Esto permite al gestor de transacciones asegurarse de que las conexiones no se retienen
durante períodos excesivos de tiempo y que la agrupación no alcanza el número máximo de
conexiones antes de tiempo.
No obstante, aparece una ramificación negativa cuando el gestor de transacciones cierra las conexiones y devuelve la conexión a la agrupación libre una vez finalizada la transacción. Una aplicación no puede obtener una conexión en una transacción e intentar utilizarla en otra transacción. Si la aplicación lo intenta, se produce una ObjectClosedException, que a su vez es una StaleConnectionException, porque la conexión ya está cerrada.
- Si se establece el tamaño mínimo de agrupación de conexiones en 0, la agrupación de conexiones se mantiene vacía cuando el servidor de aplicaciones está inactivo durante periodos prolongados. Esto ayuda a evitar que las conexiones queden obsoletas debido a la actividad de mantenimiento en el lado de la base de datos.
- Establezca la agrupación de conexiones Tiempo de espera no utilizado en un valor menor que el valor configurado para el tiempo de espera de cortafuegos. Esto asegura que la conexión no quede obsoleta hasta el Tiempo de espera no utilizado y permite que la conexión permanezca en la agrupación libre para volver a utilizarse.
- Establezca la agrupación de conexiones Tiempo de recopilación en un valor menor que el tiempo de espera no utilizado. Cuanto menor es el valor, mayor es la frecuencia de la comprobación de hebra de mantenimiento de la agrupación y más preciso es el temporizador no utilizado. Sin embargo, las ejecuciones frecuentes de hebra de mantenimiento de la agrupación pueden degradar el rendimiento.
Si intenta utilizar una conexión huérfana o una conexión que no está disponible debido a la limpieza automática de conexiones, la excepción de conexión caducada indica que la aplicación ha intentado utilizar una conexión que ya se había devuelto a la agrupación de conexiones. Esto no significa que exista ningún problema con la conexión. No obstante, los otros casos de la excepción de conexión inactiva indican que la conexión con la base de datos ha fallado, o que está inactiva. Cuando la conexión está inactiva, no se puede recuperar, y se debe cerrar totalmente, en lugar de devolverse a la agrupación.
Detección de conexiones en punto muertoCuando una conexión con la base de datos pasa a estar inactiva, las operaciones en esa conexión generan una excepción SQL del controlador JDBC. Como una excepción SQL es una excepción bastante genérica, contiene valores de código de error y de estado que se pueden utilizar para determinar su significado. No obstante, el significado de estos estados y códigos de error varían según el proveedor de la base de datos. El tiempo de ejecución de la agrupación de conexiones mantiene una correlación de qué estado SQL y qué código de error indica una excepción de conexión inactiva para cada proveedor de base de datos soportado. Cuando el tiempo de ejecución de la agrupación de conexiones detecta una excepción SQL, comprueba si esta excepción SQL se considera una excepción de conexión inactiva para el servidor de la base de datos que se está utilizando.
Recuperación de conexiones en punto muerto- Cuando el modelo de detección de anomalías se configura para la correlación de excepciones, el servidor de aplicaciones sustituye la excepción emitida por el controlador HDBC por StaleConnectionException. En este caso, es posible que la aplicación atrape una excepción de conexión inactiva.
- Cuando el modelo de detección de anomalías se configura para la comprobación de excepciones, el servidor de aplicaciones seguirá consultando la correlación de errores para gestionar la agrupación de conexiones, pero no sustituye la excepción. En este caso, la aplicación no debería atrapar una excepción de conexión inactiva.
Debido a las diferencias entre los modelos de detección de anomalías, el servidor de aplicaciones proporciona una API que las aplicaciones pueden utilizar con cualquiera de los casos para identificar conexiones inactivas. La API es com.ibm.websphere.rsadapter.WSCallHelper.getDataStoreHelper(datasource).isConnectionError(sqlexception).
No es necesario que las aplicaciones identifiquen explícitamente una excepción de conexión inactiva. Las aplicaciones ya deben capturar la excepción java.sql.SQLException, y la excepción de conexión inactiva o la excepción que emite el controlador JDBC siempre hereda datos de java.sql.SQLException. La excepción de conexión inactiva, que puede derivarse de cualquier método que se declare para emitir la excepción SQLException, se obtiene automáticamente en el bloque de obtención general. No obstante, la identificación explícita de una excepción de conexión inactiva hace posible que una aplicación pueda recuperarse de conexiones incorrectas. Cuando el código de la aplicación identifica una excepción de conexión inactiva, debería realizar pasos explícitos para la recuperación, como volver a intentar la operación bajo una transacción y conexión nuevas.
Ejemplo: manejo de la excepción de acceso a datos: conexión inactiva
Estos códigos de ejemplo muestran cómo se manejan de forma programada las excepciones relacionadas con las conexiones inactivas para los diferentes tipos de clientes de acceso a datos en los diferentes escenarios de transacciones.
Cuando una aplicación recibe una excepción de conexión inactiva en una operación de base de datos, significa que la conexión que se está manteniendo actualmente ya no es válida. Aunque es posible obtener una excepción para una conexión inactiva en cualquier operación de base de datos, el momento más típico para ver una excepción de conexión inactiva emitida es justo después de haberla recuperado. Puesto que las conexiones están agrupadas, no se detectan anomalías en la base de datos hasta la operación inmediatamente posterior a su recuperación de la agrupación, que es la primera vez que se intenta la comunicación con la base de datos. Sólo cuando se detecta una anomalía se indica que la conexión está en punto muerto. La excepción de conexión en punto muerto se da con menos frecuencia si cada método que accede a la base de datos obtiene una nueva conexión desde la agrupación.

Antes de que la aplicación pueda obtener una nueva conexión para reintentar la operación, retrotraiga la transacción en la que estaba implicada la conexión original y empiece una nueva transacción. Puede desglosar los detalles de esta acción en las dos categorías siguientes:
- Los objetos que operan en un contexto de transacción global gestionada por beans que empezó en el mismo método que el acceso a la base de datos.
- Un servlet o un bean de
sesión con BMT (transacciones gestionadas por beans) puede iniciar una transacción global de forma explícita llamando a begin() en un objeto javax.transaction.UserTransaction, que se puede recuperar a partir del nombre o a partir del objeto EJBContext del bean.
Para comprometer una transacción gestionada por bean, la aplicación llama a commit() en el objeto UserTransaction. Para retrotraer la transacción, la aplicación llama a
rollback(). Los beans de entidad y los beans de sesión que no son de BMT no pueden iniciar de forma explícita transacciones globales.
Si un objeto que inició de forma explícita una transacción gestionada por bean recibe una excepción de conexión en punto muerto en una operación de la base de datos, cierre conexión y retrotraiga la transacción. En este punto, el desarrollador de aplicaciones puede decidir empezar una nueva transacción, obtener una nueva conexión y reintentar la operación.
El siguiente fragmento de código muestra un ejemplo de cómo manejar las excepciones de conexión inactiva en este caso://get a userTransaction javax.transaction.UserTransaction tran = getSessionContext().getUserTransaction(); //retry indica si se ha de reintentar o no //numOfRetries indica el número de reintentos // realizados boolean retry = false; int numOfRetries = 0; java.sql.Connection conn = null; java.sql.Statement stmt = null; do { try { //iniciar una transacción tran.begin(); //Presupone que ya se ha obtenido un origen de datos //desde JNDI conn = ds.getConnection(); conn.setAutoCommit(false); stmt = conn.createStatement(); stmt.execute("INSERT INTO EMPLOYEES VALUES (0101, 'Bill', 'R', 'Smith')"); tran.commit(); retry = false; } catch(java.sql.SQLException sqlX) { // Si el error indica que la conexión está inactiva, // restituir y reintentar la acción if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { try { tran.rollback(); } catch (java.lang.Exception e) { //manejar la excepción //generalmente, se puede ignorar } if (numOfRetries < 2) { retry = true; numOfRetries++; } else { retry = false; } } else { //manejar con otra excepción de base de datos retry = false } } finally { //borrar siempre los recursos JDBC try { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } try { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } } } while (retry) ;
- Los objetos que operan en un contexto de transacción global que no empezó en el mismo método que el acceso a la base de datos.
- Cuando el objeto que recibe la excepción de conexión en punto muerto
no tiene control directo sobre la transacción, como en el caso de una
transacción gestionada por contenedor, el objeto debe marcar la transacción para retrotraerla,
e indicar al llamante que vuelva a intentar la transacción. En la mayoría
de los casos, esto se puede hacer generando una excepción de aplicación para indicar que se vuelva a intentar la operación. Sin embargo, esta acción no siempre está permitida y a menudo
se define un método para que genere solamente una excepción determinada.
Este es el caso con los métodos ejbLoad() y ejbStore() en un enterprise
bean. Los dos ejemplos siguientes describen cada uno de estos casos.
- Ejemplo 1: El método de acceso a la base de datos crea una excepción de aplicación.
- Cuando el método que accede a la base de datos puede generar libremente la excepción que
necesita, el método recomendado es captar la excepción de conexión en punto muerto y volver a generar
alguna excepción de la aplicación que se puede interpretar para reintentar el método. El ejemplo siguiente muestra un cliente EJB llamando a un método de un bean de
entidad con una demarcación de transacción TX_REQUIRED, lo que significa que
el contenedor inicia una transacción global cuando se llama a insertValue():
public class MyEJBClient { //... aquí otros métodos ... public void myEJBClientMethod() { MyEJB myEJB = myEJBHome.findByPrimaryKey("myEJB"); boolean retry = false; do { try { retry = false; myEJB.insertValue(); } catch(RetryableConnectionException retryable) { retry = true; } catch(Exception e) { /* handle some other problem */ } } while (retry); } } //finalizar MyEJBClient public class MyEJB implements javax.ejb.EntityBean { //... aquí otros métodos ... public void insertValue() throws RetryableConnectionException, java.rmi.EJBException { try { conn = ds.getConnection(); stmt = conn.createStatement(); stmt.execute("INSERT INTO my_table VALUES (1)"); } catch(java.sql.SQLException sqlX) { // Determinar si el error indica que la conexión está inactiva if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { getSessionContext().setRollbackOnly(); throw new RetryableConnectionException(); } else { //manejar otros problemas de base de datos } } finally { //borrar siempre los recursos JDBC try { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } try { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } } } } //finalizar MyEJB
En primer lugar, MyEJBClient obtiene un bean MyEJB de la interfaz de factoría, que se presupone que se ha recuperado previamente desde JNDI (Java Naming and Directory Interface). A continuación, llama a insertValue() en el bean. En el bean, el método obtiene una conexión e intenta insertar un valor en una tabla. Si uno de los métodos no se ejecuta correctamente con una excepción de conexión en punto muerto, marca la transacción para rollbackOnly (lo que obliga al llamante a restituir esta transacción) y genera una excepción de conexión reintentable nueva, lo que borra los recursos antes de que se genere la excepción. La conexión reintentable es simplemente una excepción definida por la aplicación que indica al llamante que vuelva a intentar el método. El llamante supervisa la excepción de conexión reintentable y, si se capta, reintenta el método. En este ejemplo, dado que el contenedor inicia y finaliza la transacción; no es necesaria ninguna gestión de transacciones en el cliente ni en el servidor. Por supuesto, el cliente podría iniciar una transacción gestionada por beans y el comportamiento seguiría siendo el mismo, siempre que el cliente haya comprometido o restituido también la transacción.
- Ejemplo 2: El método de acceso a la base de datos crea una excepción de sólo remota o una excepción de EJB.
- No todos los métodos pueden generar excepciones definidas por la aplicación. Si utiliza BMP (persistencia generada por beans), utilice los métodos
ejbLoad() y ejbStore() para almacenar el estado del bean. Las únicas excepciones emitidas a partir de estos métodos son
java.rmi.Remote o javax.ejb.EJB, por lo que no puede
utilizar nada que se parezca al ejemplo anterior.Si utiliza CMP (persistencia gestionada por contenedor), el contenedor maneja el bean de persistencia y es el contenedor el que ve la excepción de conexión inactiva. Si se detecta una conexión inactiva cuando se devuelve la excepción al cliente, simplemente se trata de una excepción remota, por lo tanto, un simple bloque de obtención no será suficiente. Hay un modo de determinar si la causa raíz de una excepción remota es una excepción de conexión inactiva. Cuando se genera una excepción remota para envolver otra excepción, normalmente se retiene la excepción original. Todas las instancias de excepción remota tienen una propiedad detallada cuyo tipo es java.lang.Throwable. Con este detalle, se puede localizar la excepción original y, si se trata de una excepción de conexión inactiva, se puede volver a intentar la transacción. En realidad, cuando una de estas excepciones remotas fluye de una API de Máquina virtual Java a la siguiente se pierden los detalles, por lo tanto, es mejor iniciar la transacción en el mismo servidor en que se produce el acceso a los datos. Por este motivo, el ejemplo siguiente muestra un bean de entidad al que accede un bean de sesión con una demarcación de transacción gestionada por bean.
public class MySessionBean extends javax.ejb.SessionBean { ... aquí otros métodos ... public void mySessionBMTMethod() throws java.rmi.EJBException { javax.transaction.UserTransaction tran = getSessionContext().getUserTransaction(); boolean retry = false; do { try { retry = false; tran.begin(); // hace que se invoque ejbLoad() myBMPBean.myMethod(); // hace que se invoque ejbStore() tran.commit(); } catch(java.rmi.EJBException re) { try { tran.rollback(); } catch (Exception e) { //can ignore } if (causedByStaleConnection(re)) retry = true; else throw re; } catch (Exception e) { // manejar otro problema } finally { //borrar siempre los recursos JDBC try { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } try { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } } } while (retry); } public boolean causedByStaleConnection(java.rmi.EJBException re) { // Buscar errores en cadena de excepciones // que indiquen una conexión inactiva for (Throwable t = re; t != null; t = t.getCause()) if (t instanceof RetryableConnectionException) return true; // No se ha determinado como inactiva return false; } } public class MyEntityBean extends javax.ejb.EntityBean { ... aquí otros métodos ... public void ejbStore() throws java.rmi.EJBException { try { conn = ds.getConnection(); stmt = conn.createStatement(); stmt.execute("UPDATE my_table SET value=1 WHERE primaryKey=" + myPrimaryKey); } catch(java.sql.SQLException sqlX) { // Determinar si el error indica que la conexión está inactiva if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { // restituir la transacción cuando regrese el método getEntityContext().setRollbackOnly(); throw new java.rmi.EJBException( "Exception occurred in ejbStore", new RetryableConnectionException(sqlX)); } else { // manejar otro problema } } finally { //borrar siempre los recursos JDBC try { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } try { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //generalmente se puede ignorar } } } }
En mySessionBMTMethod() del ejemplo anterior:- El bean de sesión recupera en primera lugar un objeto UserTransaction del contexto de sesión y luego inicia una transacción global.
- A continuación, llama a un método en el bean de entidad, el cual llama al método ejbLoad(). Si ejbLoad() se ejecuta correctamente, el cliente compromete la transacción, lo que hace que se llame al método ejbStore().
- En ejbStore(), el bean de entidad obtiene una conexión y graba su estado en la base de datos; si la conexión recuperada está caducada, se marca como rollbackOnly y se genera una EJBException nueva que envuelve la RetryableConnectionException. A continuación, el cliente capta esta excepción, borra los recursos JDBC, restituye la transacción y llama a causedByStaleConnection(), que determina si en algún lugar de la excepción se encuentra la excepción de conexión en punto muerto.
- Si el método devuelve el valor true, se establece el distintivo retry y se reintenta la transacción. De lo contrario, se vuelve a emitir la excepción para el llamante.
- El método causedByStaleConnection() busca por la cadena de atributos detallados para buscar la excepción original. En el momento en que la excepción se devuelve finalmente al cliente, es posible que contenga varias excepciones envueltas, por lo tanto, el método continúa buscando hasta que encuentra una excepción de conexión inactiva y se devuelve true; de lo contrario, no habrá ninguna excepción de conexión inactiva en la lista y se devolverá false.
- Si habla con un bean CMP en lugar de un bean BMP, el bean de sesión es el mismo. El método ejbStore() del bean CMP estará muy probablemente vacío y después de llamar al contenedor éste permanecerá en el bean con el código generado.
- Si durante la persistencia se produce una excepción de conexión en punto muerto, se envolverá con una excepción remota y se devolverá al llamante. Una vez más, el método causedByStaleConnection() buscará en la cadena de excepciones hasta encontrar la excepción raíz que será de conexión en punto muerto.
- Los objetos que operan en un contexto de transacción local
- Cuando se ejecuta una
operación de base de datos fuera del contexto de transacción global, el contenedor
empieza implícitamente una transacción local.
Esto incluye servlets o JSP que no empiezan
transacciones con la interfaz UserTransaction, así como enterprise beans que se
ejecutan en contextos de transacción sin especificar. Al igual que con las transacciones globales, debe retrotraer la transacción local antes de volver a intentar la operación. En estos casos, el contenedor de transacción local finaliza normalmente cuando finaliza el
método de empresa. La única excepción es si está utilizando sesiones de actividad. En este caso, la sesión de actividad deberá finalizar antes de intentar obtener una nueva conexión.
Cuando la transacción local se produce en un enterprise bean que se ejecuta en un contexto de transacción sin especificar, el objeto de cliente de enterprise bean, fuera del contenedor de transacción local, podría utilizar el método descrito en el párrafo anterior para volver a intentar la transacción. Sin embargo, cuando el contenedor de transacción local forma parte de un servlet o un archivo JSP, no hay ningún objeto de cliente disponible para volver a intentar la operación. Debido a esta razón, se recomienda evitar las operaciones de bases de datos en servlets y archivos JSP, a menos que formen parte de una transacción de usuario.
Conexión en punto muerto en sistemas Linux
Es posible que tenga que establecer un bucle de retorno para acceder a bases de datos DB2 desde el servidor de aplicaciones en una plataforma Linux.
- Utilización del controlador JDBC de DB2 Universal Tipo 2 para la conexión con una base de datos DB2 local
- Utilización del controlador JDBC de DB2 Universal de tipo 2 para acceder a DB2 para z/OS mediante una instalación de DB2 Connect en la misma máquina que el servidor de aplicaciones. El problema se produce sólo si DB2 Connect impide que los clientes locales se ejecuten desde un agente. Esto es, si el valor de DB2_IN_APP_PROCESS no es el valor por omisión o si el valor es Yes. Establezca el valor en No solucionar el problema y evite realizar el procedimiento siguiente.
'71' -SQLCC_ERR_CONN_CLOSED_BY_PARTNER y SQLCODE -XXXX
db2 catalog TCPIP node RHOST remote LHOST server 50000 db2 uncatalog db WAS db2 catalog db WAS as WASAlias at node loop authentication server //Si se conecta a WASAlias, es una conexión mediante bucle de retorno; //Si se conecta a WAS, es una conexión "normal". db2 catalog db WASAlias as WAS at node RHOST
Ejemplo: manejo de las excepciones de conexiones JDBC del servlet
En el siguiente código de ejemplo se muestra cómo se establecen las propiedades de gestión de transacciones y de gestión de conexiones como, por ejemplo, los reintentos de operaciones, para tratar las excepciones de conexiones inactivas dentro de una transacción JDBC del servlet.
- inicializa un servlet
- busca un origen de datos
- especifica los mensajes de error, los reintentos de conexiones y los requisitos de retrotracción de transacciones
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// Importar paquetes JDBC y paquetes de servicio de denominación.
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import javax.transaction.*;
import com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException;
import com.ibm.websphere.rsadapter.WSCallHelper;
public class EmployeeListTran extends HttpServlet {
private static DataSource ds = null;
private UserTransaction ut = null;
private static String title = "Employee List";
// ****************************************************************
// * Inicializar el servlet al cargarlo por primera vez. *
// * Obtener información del archivo de propiedades y buscar el *
// * objeto DataSource de JNDI para mejorar el rendimiento de los *
// * métodos de servicio del servlet. *
// ****************************************************************
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
getDS();
}
// ****************************************************************
// * Realizar la búsqueda JNDI del objeto DataSource. *
// * Objetos de transacciones de usuario. *
// * Este método se invoca desde init() y desde el método de *
// * de DataSource resulta nulo. *
// ****************************************************************
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Realizar búsqueda de servicio de denominación para obtener objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
} catch (Exception e) {
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
// ****************************************************************
// * Responder a solicitudes GET de usuario *
// ****************************************************************
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
// Establecer retryCount en el número de reintentos que desea después de
// stale connection exception
int retryCount = 5;
// Si el código de base de datos se procesa bien, se establecerá error = false
boolean error = true;
do
{
try
{
//Iniciar una transacción nueva
ut.begin();
// Obtener un objeto de conexión conn mediante la fábrica DataSource.
conn = ds.getConnection();
// Ejecutar consulta DB mediante codificación JDBC estándar.
stmt = conn.createStatement();
String query = "Select FirstNme, MidInit, LastName " +
"from Employee ORDER BY LastName";
rs = stmt.executeQuery(query);
while (rs.next())
{
employeeList.addElement(rs.getString(3) + ", "+ rs.getString(1)" + " + rs.getString(2));
}
//Definir error = false para indicar que la base de datos ha finalizado bien su trabajo
error=false;
}
catch (SQLException sqlX)
{
// Determinar si se ha excedido el tiempo de espera de la solicitud de conexión.
// Este código funciona independientemente del modelo de detección de errores
// que se utilice. Si se habilita la correlación de excepciones,
// tendrá que buscar ConnectionWaitTimeoutException.
// Si se ha habilitado la comprobación de excepciones, busque
// SQLTransientConnectionException con una
// ConnectionWaitTimeoutException encadenada.
if ( sqlX instanceof ConnectionWaitTimeoutException
|| sqlX instanceof SQLTransientConnectionException
&& sqlX.getCause() instanceof ConnectionWaitTimeoutException)
{
// Esta excepción se genera si no se puede obtener una conexión de la
// agrupación en un período de tiempo configurable. Si aparece mucho
// esta excepción la agrupación de conexiones se ha ajustado mal
System.out.println("Connection Wait Timeout Exception during get connection or
process SQL: " + c.getMessage());
//En general, no se desean reintentos después de esta excepción, así que establezca el número de reintentos en 0
//y restituya la transacción
try
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Se genera para indicar que la hebra no puede restituir la transacción.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise)
{
//Se genera si la hebra actual no está asociada a una transacción.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
else if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
//Restituya la transacción, reintente varias veces obtener una conexión válida
//, visualice un mensaje de error si la conexión sigue sin obtenerse.
System.out.println("Connection is stale: " + sc.getMessage());
try
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Se genera para indicar que la hebra no puede restituir la transacción.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise)
{
//Se genera si la hebra actual no está asociada a una transacción.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
if (--retryCount == 0)
{
System.out.println("Five stale connection exceptions, displaying error page.");
}
}
else
{
System.out.println("SQL Exception during get connection or process SQL: " + sq.getMessage());
//En general, no se desean reintentos después de esta excepción, así que establezca el número de reintentos en 0
//y restituya la transacción
try
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Se genera para indicar que la hebra no puede restituir la transacción.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise)
{
//Se genera si la hebra actual no está asociada a una transacción.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
}
catch (NotSupportedException nse)
{
//La genera el método UerTransaction begin si la hebra ya está asociada con una
//transacción y la implementación del gestor de transacciones no soporta transacciones
//anidadas.
System.out.println("NotSupportedException on User Transaction begin: " + nse.getMessage());
}
catch (SystemException se)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("SystemException in User Transaction: " +se.getMessage());
}
catch (Exception e)
{
System.out.println("Exception in get connection or process SQL: " + e.getMessage());
//En general, no se desean reintentos después de esta excepción, así que establezca el número de reintentos en 5
//y restituya la transacción
try
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Se genera para indicar que la hebra no puede restituir la transacción.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise)
{
//Se genera si la hebra actual no está asociada a una transacción.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no se cierra la conexión
// real, sino que se libera para que pueda reutilizarse en la agrupación.
if (rs != null)
{
try
{
rs.close();
}
catch (Exception e)
{
System.out.println("Close Resultset Exception: " + e.getMessage());
}
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
try
{
ut.commit();
}
catch (RollbackException re)
{
//Se genera para indicar que la transacción se ha restituido en lugar de comprometerse.
System.out.println("User Transaction Rolled back!" + re.getMessage());
}
catch (SecurityException se)
{
//Se genera para indicar que la hebra no puede comprometer la transacción.
System.out.println("Security Exception thrown on transaction commit: " + se.getMessage());
}
catch (IllegalStateException ise)
{
//Se genera si la hebra actual no está asociada a una transacción.
System.out.println("Illegal State Exception thrown on transaction commit: " + ise.getMessage());
}
catch (SystemException sye)
{
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("System Exception thrown on transaction commit: " + sye.getMessage());
}
catch (Exception e)
{
System.out.println("Exception thrown on transaction commit: " + e.getMessage());
}
}
}
while ( error==true && retryCount > 0 );
// Preparar y devolver respuesta HTML, impedir el almacenamiento del contenido
// dinámico en la memoria caché de los navegadores.
res.setContentType("text/html");
res.setHeader("Pragma", "no-cache");
res.setHeader("Cache-Control", "no-cache");
res.setDateHeader("Expires", 0);
try
{
ServletOutputStream out = res.getOutputStream();
out.println("<HTML>");
out.println("<HEAD><TITLE>" + title + "</TITLE></HEAD>");
out.println("<BODY>");
if (error==true)
{
out.println("<H1>Se ha producido un error al procesar esta petición.</H1>" +
"Vuelva a intentar la solicitud o póngase en contacto con " +
" el administrador del sistema <a href='mailto:sysadmin@my.com'></a>");
}
else if (employeeList.isEmpty())
{
out.println("<H1>Employee List is Empty</H1>");
}
else
{
out.println("<H1>Employee List </H1>");
for (int i = 0; i < employeeList.size(); i++)
{
out.println(employeeList.elementAt(i) + "<BR>");
}
}
out.println("</BODY></HTML>");
out.close();
}
catch (IOException e)
{
System.out.println("HTML response exception: " + e.getMessage());
}
}
}
Ejemplo: manejo de excepciones de conexión para beans de sesión en transacciones de base de datos gestionadas por contenedor
El siguiente código de ejemplo muestra cómo se restituyen las transacciones y se emiten excepciones al cliente de bean en casos de excepciones de conexiones inactivas.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import javax.ejb.*;
import javax.naming.*;
import com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException;
import com.ibm.websphere.rsadapter.WSCallHelper;
/*************************************************************************************
* Este bean se ha diseñado para mostrar las conexiones de base de datos *
* de un bean de sesión de transacciones gestionadas por contenedor. Su atributo *
* de transacción debe establecerse en TX_REQUIRED o TX_REQUIRES_NEW. *
**************************************************************************************
*/
public class ShowEmployeesCMTBean implements SessionBean {
private javax.ejb.SessionContext mySessionCtx = null;
final static long serialVersionUID = 3206093459760846163L;
private javax.sql.DataSource ds;
//************************************************************************************
//* ejbActivate llama al método getDS que ejecuta la búsqueda JNDI de DataSource.
//* Dado que la búsqueda de DataSource se ejecuta en un método distinto, se puede
//* invocar desde getEmployees cuando el campo DataSource sea nulo.
//************************************************************************************
public void ejbActivate() throws java.rmi.EJBException {
getDS();
}
/**
* ejbCreate method
* @exception javax.ejb.CreateException
* @exception java.rmi.EJBException
*/
public void ejbCreate() throws javax.ejb.CreateException, java.rmi.EJBException {}
/**
* ejbPassivate method
* @exception java.rmi.EJBException
*/
public void ejbPassivate() throws java.rmi.EJBException {}
/**
* ejbRemove method
* @exception java.rmi.EJBException
*/
public void ejbRemove() throws java.rmi.EJBException {}
//************************************************************************************
//* getEmployees devuelve la consulta de base de datos para recuperar empleados
//* solo se llama a getDS si la variable DataSource es nula.
//* Como este bean de sesión utiliza transacciones gestionadas por contenedor, no puede
//* reintentar la transacción en una StaleConnectionException. Pero sí puede generar
//* una excepción a su cliente indicando que se puede reintentar la operación.
//************************************************************************************
public Vector getEmployees() throws ConnectionWaitTimeoutException, SQLException,
RetryableConnectionException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
if (ds == null) getDS();
try
{
// Obtener un objeto de conexión conn mediante la fábrica DataSource.
conn = ds.getConnection();
// Ejecutar consulta DB mediante codificación JDBC estándar.
stmt = conn.createStatement();
String query = "Select FirstNme, MidInit, LastName " +
"from Employee ORDER BY LastName;"
rs = stmt.executeQuery(query);
while (rs.next())
{
employeeList.addElement(rs.getString(3) + ", "+ rs.getString(1)" + " + rs.getString(2));
}
}
catch (SQLException sqlX)
{
// Determinar si la conexión está inactiva
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
// Restituya la transacción y genere una excepción para el cliente indicando que
// puede volver a intentar la transacción si lo desea.
System.out.println("Connection is stale: " + sqlX.getMessage());
System.out.println("Rolling back transaction and throwing RetryableConnectionException");
mySessionCtx.setRollbackOnly();
throw new RetryableConnectionException(sqlX.toString());
}
// Determinar si se ha excedido el tiempo de espera de la solicitud de conexión.
else if ( sqlX instanceof ConnectionWaitTimeoutException
|| sqlX instanceof SQLTransientConnectionException
&& sqlX.getCause() instanceof ConnectionWaitTimeoutException)
{
// Esta excepción se genera si no se puede obtener una conexión de la
// agrupación en un período de tiempo configurable. Si aparece mucho
// esta excepción la agrupación de conexiones se ha ajustado mal
System.out.println("Connection Wait Timeout Exception during get connection or process SQL: " +
sqlX.getMessage());
throw sqlX instanceof ConnectionWaitTimeoutException ?
sqlX :
(ConnectionWaitTimeoutException) sqlX.getCause();
}
else
{
//Generar una excepción remota restituirá automáticamente la transacción
//gestionada por contenedor
System.out.println("SQL Exception during get connection or process SQL: " +
sqlX.getMessage());
throw sqlX;
}
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no se cierra la conexión
// real, sino que se libera para que pueda reutilizarse en la agrupación.
if (rs != null)
{
try
{
rs.close();
}
catch (Exception e)
{
System.out.println("Close Resultset Exception: " +
e.getMessage());
}
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " +
e.getMessage());
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
return employeeList;
}
/**
* getSessionContext method
* @return javax.ejb.SessionContext
*/
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
//************************************************************************************
//* El método getDS realiza la búsqueda JNDI de origen de datos.
//* Este método se llama desde ejbActivate y desde getEmployees si el origen de datos
//* es nulo.
//************************************************************************************
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Realizar búsqueda de servicio de denominación para obtener objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
}
catch(Exception e){
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* setSessionContext method
* @param ctx javax.ejb.SessionContext
* @exception java.rmi.EJBException
*/
public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.EJBException {
mySessionCtx = ctx;
}
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz de factoría para el bean de sesión
*/
public interface ShowEmployeesCMTHome extends javax.ejb.EJBHome {
/**
* método create para un bean de sesión
* @return WebSphereSamples.ConnPool.ShowEmployeesCMT
* @exception javax.ejb.CreateException
* @exception java.rmi.RemoteException
*/
WebSphereSamples.ConnPool.ShowEmployeesCMT create() throws javax.ejb.CreateException,
java.rmi.RemoteException;
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz remota de Enterprise Java Bean
*/
public interface ShowEmployeesCMT extends javax.ejb.EJBObject {
/**
*
* @return java.util.Vector
*/
java.util.Vector getEmployees() throws java.sql.SQLException, java.rmi.RemoteException,
ConnectionWaitTimeoutException, WebSphereSamples.ConnPool.RetryableConnectionException;
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Excepción que indica que puede reintentarse la operación
* Fecha de creación: (4/2/2001 10:48:08 AM)
* @author: Administrador
*/
public class RetryableConnectionException extends Exception {
/**
* RetryableConnectionException constructor.
*/
public RetryableConnectionException() {
super();
}
/**
* RetryableConnectionException constructor.
* @param s java.lang.String
*/
public RetryableConnectionException(String s) {
super(s);
}
}
Ejemplo: manejo de excepciones de conexión para beans de sesión en transacciones de base de datos gestionadas por beans
El siguiente código de ejemplo muestra las opciones para tratar las excepciones de conexiones inactivas. Puede establecer diferentes parámetros de gestión de transacciones y de gestión de conexiones como, por ejemplo, el número de reintentos de operaciones y el intervalo de tiempo de espera de conexión.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import javax.ejb.*;
import javax.naming.*;
import javax.transaction.*;
import com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException;
import com.ibm.websphere.rsadapter.WSCallHelper;
/**********************************************************************************
* Este bean se ha diseñado para mostrar las conexiones de base de datos en un *
* bean de sesión de transacciones gestionadas por contenedor. Su atributo *
* debe establecerse en TX_BEANMANAGED.
**********************************************************************************/
public class ShowEmployeesBMTBean implements SessionBean {
private javax.ejb.SessionContext mySessionCtx = null;
final static long serialVersionUID = 3206093459760846163L;
private javax.sql.DataSource ds;
private javax.transaction.UserTransaction userTran;
//************************************************************************************
//* ejbActivate llama a getDS que efectúa la búsqueda JNDI de DataSource
//* Dado que la búsqueda de DataSource se ejecuta en un método distinto, se puede
//* invocar desde getEmployees cuando el campo DataSource sea nulo.
//************************************************************************************
public void ejbActivate() throws java.rmi.EJBException {
getDS();
}
/**
* ejbCreate method
* @exception javax.ejb.CreateException
* @exception java.rmi.EJBException
*/
public void ejbCreate() throws javax.ejb.CreateException, java.rmi.EJBException {}
/**
* ejbPassivate method
* @exception java.rmi.EJBException
*/
public void ejbPassivate() throws java.rmi.EJBException {}
/**
* ejbRemove method
* @exception java.rmi.EJBException
*/
public void ejbRemove() throws java.rmi.EJBException {}
//************************************************************************************
//* getEmployees devuelve la consulta de base de datos para recuperar empleados
//* solo se llama a getDS si la variable DataSource o userTran es nula.
//* Si se produce una conexión inactiva, el bean reintenta la transacción 5 veces,
//* luego genera una EJBException.
//************************************************************************************
public Vector getEmployees() throws EJBException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
// Establecer retryCount en el número de reintentos que desea después de
// conexión inactiva
int retryCount = 5;
// Si el código de base de datos se procesa bien, se establecerá error = false
boolean error = true;
if (ds == null || userTran == null) getDS();
do
{
try
{
//try/catch block for UserTransaction work
//Begin the transaction
userTran.begin();
try
{
//try/catch block for database work
// Obtener un objeto de conexión conn mediante la fábrica DataSource.
conn = ds.getConnection();
// Ejecutar consulta DB mediante codificación JDBC estándar.
stmt = conn.createStatement();
String query = "Select FirstNme, MidInit, LastName " +
"from Employee ORDER BY LastName";
rs = stmt.executeQuery(query);
while (rs.next())
{
employeeList.addElement(rs.getString(3) + ", " + rs.getString(1) + " " + rs.getString(2));
}
//Definir error = false, porque todas las operaciones de base de datos finalizan bien
error = false;
}
catch (SQLException sqlX)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
// Restituya la transacción y genere una excepción para el cliente indicando que
// puede volver a intentar la transacción si lo desea.
System.out.println("Stale connection: " +
se.getMessage());
userTran.rollback();
if (--retryCount == 0)
{
//Si ya ha realizado el número de reintentos solicitado, generar una EJBException.
throw new EJBException("Transaction Failure: " + sqlX.toString());
}
else
{
System.out.println("Retrying transaction, retryCount = " +
retryCount);
}
}
else if (sqlX instanceof ConnectionWaitTimeoutException
|| sqlX instanceof SQLTransientConnectionException
&& sqlX.getCause() instanceof ConnectionWaitTimeoutException)
{
// Esta excepción se genera si no se puede obtener una conexión de la
// agrupación en un período de tiempo configurable. Si aparece mucho
// esta excepción la agrupación de conexiones se ha ajustado mal
System.out.println("Connection request timed out: " +
sqlX.getMessage());
userTran.rollback();
throw new EJBException("Transaction failure: " + sqlX.getMessage());
}
else
{
// Este catch maneja todas las demás excepciones SQL
System.out.println("SQL Exception during get connection or process SQL: " +
sqlX.getMessage());
userTran.rollback();
throw new EJBException("Transaction failure: " + sqlX.getMessage());
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no se cierra la conexión
// real, sino que se libera para que pueda reutilizarse en la agrupación.
if (rs != null) {
try {
rs.close();
}
catch(Exception e){
System.out.println("Close Resultset Exception: " + e.getMessage());
}
}
if (stmt != null) {
try {
stmt.close();
}
catch(Exception e){
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null) {
try {
conn.close();
}
catch(Exception e){
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
if (!error) {
//La tarea de base de datos se ha realizado correctamente, comprometer la transacción
userTran.commit();
}
//Capturar excepciones UserTransaction
}
catch (NotSupportedException nse) {
//La genera el método UerTransaction begin si la hebra ya está asociada con una
//transacción y la implementación del gestor de transacciones no soporta transacciones anidadas.
System.out.println("NotSupportedException on User Transaction begin: " +
nse.getMessage());
throw new EJBException("Transaction failure: " + nse.getMessage());
}
catch (RollbackException re) {
//Se genera para indicar que la transacción se ha restituido en lugar de comprometerse.
System.out.println("User Transaction Rolled back!" + re.getMessage());
throw new EJBException("Transaction failure: " + re.getMessage());
}
catch (SystemException se) {
//Se genera si el gestor de transacciones encuentra una condición de error imprevista
System.out.println("SystemException in User Transaction: "+ se.getMessage());
throw new EJBException("Transaction failure: " + se.getMessage());
}
catch(Exception e){
//Manejar excepciones genéricas o imprevistas
System.out.println("Exception in User Transaction: " + e.getMessage());
throw new EJBException("Transaction failure: " + e.getMessage());
}
}
while (error);
return employeeList;
}
/**
* getSessionContext method comment
* @return javax.ejb.SessionContext
*/
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
//************************************************************************************
//* getDS efectúa la búsqueda JNDI de DataSource.
//* Este método se llama desde ejbActivate y desde getEmployees si el objeto DataSource
//* es nulo.
//************************************************************************************
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Realizar búsqueda de servicio de denominación para obtener objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
//Crear el objeto UserTransaction
userTran = mySessionCtx.getUserTransaction();
}
catch(Exception e){
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* setSessionContext method
* @param ctx javax.ejb.SessionContext
* @exception java.rmi.EJBException
*/
public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.EJBException {
mySessionCtx = ctx;
}
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz de factoría para el bean de sesión
*/
public interface ShowEmployeesBMTHome extends javax.ejb.EJBHome {
/**
* método create para un bean de sesión
* @return WebSphereSamples.ConnPool.ShowEmployeesBMT
* @exception javax.ejb.CreateException
* @exception java.rmi.RemoteException
*/
WebSphereSamples.ConnPool.ShowEmployeesBMT create() throws javax.ejb.CreateException,
java.rmi.RemoteException;
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz remota de Enterprise Java Bean
*/
public interface ShowEmployeesBMT extends javax.ejb.EJBObject {
/**
*
* @return java.util.Vector
*/
java.util.Vector getEmployees() throws java.rmi.RemoteException, javax.ejb.EJBException;
}
Ejemplo: manejo de excepciones de conexión para beans BMP en transacciones de base de datos gestionadas por contenedor
El siguiente código de ejemplo muestra cómo se restituyen las transacciones y se emiten excepciones al cliente de bean en casos de excepciones de conexiones inactivas.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2005,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
import java.util.*;
import javax.ejb.*;
import java.sql.*;
import javax.sql.*;
import javax.ejb.*;
import javax.naming.*;
import com.ibm.websphere.rsadapter.WSCallHelper;
/**
* Esta es una clase de bean de entidad con cinco campos BMP
* String firstName, String lastName, String middleInit
* String empNo, int edLevel
*/
public class EmployeeBMPBean implements EntityBean {
private javax.ejb.EntityContext entityContext = null;
final static long serialVersionUID = 3206093459760846163L;
private java.lang.String firstName;
private java.lang.String lastName;
private String middleInit;
private javax.sql.DataSource ds;
private java.lang.String empNo;
private int edLevel;
/**
* ejbActivate method
* ejbActivate calls getDS(), which performs the
* JNDI lookup for the datasource.
*/
public void ejbActivate() {
getDS();
}
/**
* ejbCreate method for a BMP entity bean
* @return WebSphereSamples.ConnPool.EmployeeBMPKey
* @param key WebSphereSamples.ConnPool.EmployeeBMPKey
* @exception javax.ejb.CreateException
*/
public WebSphereSamples.ConnPool.EmployeeBMPKey ejbCreate(String empNo,
String firstName, String lastName, String middleInit, int edLevel) throws
javax.ejb.CreateException {
Connection conn = null;
PreparedStatement ps = null;
if (ds == null) getDS();
this.empNo = empNo;
this.firstName = firstName;
this.lastName = lastName;
this.middleInit = middleInit;
this.edLevel = edLevel;
String sql = "insert into Employee (empNo, firstnme, midinit, lastname,
edlevel) values (?,?,?,?,?)";
try {
conn = ds.getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1, empNo);
ps.setString(2, firstName);
ps.setString(3, middleInit);
ps.setString(4, lastName);
ps.setInt(5, edLevel);
if (ps.executeUpdate() != 1){
System.out.println("ejbCreate Failed to add user.");
throw new CreateException("Failed to add user.");
}
}
catch (SQLException se)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(se))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
// Restituya la transacción y genere una excepción para el cliente indicando que
// puede volver a intentar la transacción si lo desea.
System.out.println("Connection is stale: " + se.getMessage());
throw new CreateException(se.getMessage());
}
else
{
System.out.println("SQL Exception during get connection or process SQL: " +
se.getMessage());
throw new CreateException(se.getMessage());
}
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no se cierra la conexión
// real, sino que se libera para que pueda reutilizarse en la agrupación.
if (ps != null)
{
try
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
return new EmployeeBMPKey(this.empNo);
}
/**
* ejbFindByPrimaryKey method
* @return WebSphereSamples.ConnPool.EmployeeBMPKey
* @param primaryKey WebSphereSamples.ConnPool.EmployeeBMPKey
* @exception javax.ejb.FinderException
*/
public WebSphereSamples.ConnPool.EmployeeBMPKey
ejbFindByPrimaryKey(WebSphereSamples.ConnPool.EmployeeBMPKey primaryKey)
javax.ejb.FinderException {
loadByEmpNo(primaryKey.empNo);
return primaryKey;
}
/**
* ejbLoad method
*/
public void ejbLoad() {
try {
EmployeeBMPKey pk = (EmployeeBMPKey) entityContext.getPrimaryKey();
loadByEmpNo(pk.empNo);
} catch (FinderException fe) {
throw new EJBException("Cannot load Employee state from database.");
}
}
/**
* ejbPassivate method
*/
public void ejbPassivate() {}
/**
* método ejbPostCreate para un bean de entidad BMP
* @param key WebSphereSamples.ConnPool.EmployeeBMPKey
*/
public void ejbPostCreate(String empNo, String firstName, String lastName, String middleInit,
int edLevel) {}
/**
* ejbRemove method
* @exception javax.ejb.RemoveException
*/
public void ejbRemove() throws javax.ejb.RemoveException
{
if (ds == null)
GetDS();
String sql = "delete from Employee where empNo=?";
Connection con = null;
PreparedStatement ps = null;
try
{
con = ds.getConnection();
ps = con.prepareStatement(sql);
ps.setString(1, empNo);
if (ps.executeUpdate() != 1)
{
throw new EJBException("Cannot remove employee: " + empNo);
}
}
catch (SQLException se)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(se))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
// Restituya la transacción y genere una excepción para el cliente indicando que
// puede volver a intentar la transacción si lo desea.
System.out.println("Connection is stale: " + se.getMessage());
throw new EJBException(se.getMessage());
}
else
{
System.out.println("SQL Exception during get connection or process SQL: " +
se.getMessage());
throw new EJBException(se.getMessage());
}
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no se cierra la conexión
// real, sino que se libera para que pueda reutilizarse en la agrupación.
if (ps != null)
{
try
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (con != null)
{
try
{
con.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
}
/**
* Obtener edLevel de empleado
* Fecha de creación: (4/20/2001 3:46:22 PM)
* @return int
*/
public int getEdLevel() {
return edLevel;
}
/**
* getEntityContext method
* @return javax.ejb.EntityContext
*/
public javax.ejb.EntityContext getEntityContext() {
return entityContext;
}
/**
* Obtener el nombre del empleado
* Fecha de creación: (4/19/2001 1:34:47 PM)
* @return java.lang.String
*/
public java.lang.String getFirstName() {
return firstName;
}
/**
* Obtener el apellido del empleado
* Fecha de creación: (4/19/2001 1:35:41 PM)
* @return java.lang.String
*/
public java.lang.String getLastName() {
return lastName;
}
/**
* obtener la inicial del segundo apellido del empleado
* Fecha de creación: (4/19/2001 1:36:15 PM)
* @return char
*/
public String getMiddleInit() {
return middleInit;
}
/**
* Buscar DataSource desde JNDI
* Fecha de creación: (4/19/2001 3:28:15 PM)
*/
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Realizar búsqueda de servicio de denominación para obtener objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
}
catch(Exception e){
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Cargar el empleado desde la base de datos
* Fecha de creación: (4/19/2001 3:44:07 PM)
* @param empNo java.lang.String
*/
private void loadByEmpNo(String empNoKey) throws javax.ejb.FinderException
{
String sql = "select empno, firstnme, midinit, lastname, edLevel from employee where empno = ?";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
if (ds == null) getDS();
try
{
// Obtener un objeto de conexión conn mediante la fábrica DataSource.
conn = ds.getConnection();
// Ejecutar consulta DB mediante codificación JDBC estándar.
ps = conn.prepareStatement(sql);
ps.setString(1, empNoKey);
rs = ps.executeQuery();
if (rs.next())
{
empNo= rs.getString(1);
firstName=rs.getString(2);
middleInit=rs.getString(3);
lastName=rs.getString(4);
edLevel=rs.getInt(5);
}
else
{
throw new ObjectNotFoundException("Cannot find employee number " +
empNoKey);
}
}
catch (SQLException se)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(se))
{
// Esta excepción indica que la conexión con la base de datos ya no es válida.
// Restituya la transacción y genere una excepción para el cliente indicando que
// puede volver a intentar la transacción si lo desea.
System.out.println("Connection is stale: " + se.getMessage());
throw new FinderException(se.getMessage());
}
else
{
System.out.println("SQL Exception during get connection or process SQL: " +
se.getMessage());
throw new FinderException(se.getMessage());
}
}
finally
{
// Cerrar siempre la conexión en una sentencia final para que en todos los
// casos el cierre sea correcto. Al cerrar la conexión no
// se cierra la conexión real, si no que se libera de nuevo a la agrupación
// para que pueda reutilizarse.
if (rs != null)
{
try
{
rs.close();
}
catch (Exception e)
{
System.out.println("Close Resultset Exception: " + e.getMessage());
}
}
if (ps != null)
{
try
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
}
/**
* establecer el nivel de formación del empleado
* Fecha de creación: (4/20/2001 3:46:22 PM)
* @param newEdLevel int
*/
public void setEdLevel(int newEdLevel) {
edLevel = newEdLevel;
}
/**
* setEntityContext method
* @param ctx javax.ejb.EntityContext
*/
public void setEntityContext(javax.ejb.EntityContext ctx) {
entityContext = ctx;
}
/**
* establecer el nombre del empleado
* Fecha de creación: (4/19/2001 1:34:47 PM)
* @param newFirstName java.lang.String
*/
public void setFirstName(java.lang.String newFirstName) {
firstName = newFirstName;
}
/**
* establecer el apellido del empleado
* Fecha de creación: (4/19/2001 1:35:41 PM)
* @param newLastName java.lang.String
*/
public void setLastName(java.lang.String newLastName) {
lastName = newLastName;
}
/**
* establecer la inicial del segundo apellido del empleado
* Fecha de creación: (4/19/2001 1:36:15 PM)
* @param newMiddleInit char
*/
public void setMiddleInit(String newMiddleInit) {
middleInit = newMiddleInit;
}
/**
* unsetEntityContext method
*/
public void unsetEntityContext() {
entityContext = null;
}
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz remota de Enterprise Java Bean
*/
public interface EmployeeBMP extends javax.ejb.EJBObject {
/**
*
* @return int
*/
int getEdLevel() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getFirstName() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getLastName() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getMiddleInit() throws java.rmi.RemoteException;
/**
*
* @return void
* @param newEdLevel int
*/
void setEdLevel(int newEdLevel) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newFirstName java.lang.String
*/
void setFirstName(java.lang.String newFirstName) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newLastName java.lang.String
*/
void setLastName(java.lang.String newLastName) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newMiddleInit java.lang.String
*/
void setMiddleInit(java.lang.String newMiddleInit) throws java.rmi.RemoteException;
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una interfaz remota de Enterprise Java Bean
*/
public interface EmployeeBMP extends javax.ejb.EJBObject {
/**
*
* @return int
*/
int getEdLevel() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getFirstName() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getLastName() throws java.rmi.RemoteException;
/**
*
* @return java.lang.String
*/
java.lang.String getMiddleInit() throws java.rmi.RemoteException;
/**
*
* @return void
* @param newEdLevel int
*/
void setEdLevel(int newEdLevel) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newFirstName java.lang.String
*/
void setFirstName(java.lang.String newFirstName) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newLastName java.lang.String
*/
void setLastName(java.lang.String newLastName) throws java.rmi.RemoteException;
/**
*
* @return void
* @param newMiddleInit java.lang.String
*/
void setMiddleInit(java.lang.String newMiddleInit) throws java.rmi.RemoteException;
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos los derechos reservados
// Material bajo licencia, propiedad de IBM
// Derechos limitados de los usuarios del gobierno de EE.UU.: el uso, la
// duplicación o revelación queda limitada por el contrato GSA ADP Schedule con IBM Corp.
//
// IBM RENUNCIA A TODAS LAS GARANTÍAS RELACIONADAS CON ESTE SOFTWARE, INCLUIDAS
// LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD E IDONEIDAD PARA UNA FINALIDAD
// DETERMINADA. EN NINGÚN CASO IBM SE HACE RESPONSABLE DE DAÑOS ESPECIALES, INDIRECTOS
// O COMO CONSECUENCIA RESULTANTES DE LA PÉRDIDA DE USO, DE DATOS O
// BENEFICIOS, YA SEA DEBIDO CONTRATO, NEGLIGENCIA O CUALQUIER OTRA
// ACCIÓN RELACIONADA O ASOCIADA CON EL USO O CON EL RENDIMIENTO DE ESTE
// SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta es una clase de clave primaria para el bean de entidad
**/
public class EmployeeBMPKey implements java.io.Serializable {
public String empNo;
final static long serialVersionUID = 3206093459760846163L;
/**
* EmployeeBMPKey() constructor
*/
public EmployeeBMPKey() {
}
/**
* EmployeeBMPKey(String key) constructor
*/
public EmployeeBMPKey(String key) {
empNo = key;
}
/**
* método equals
* - el usuario debe proporcionar una implementación correcta del método equal. El método
* generado presupone que la clave es un objeto String.
*/
public boolean equals (Object o) {
if (o instanceof EmployeeBMPKey)
return empNo.equals(((EmployeeBMPKey)o).empNo);
else
return false;
}
/**
* método hashCode
* - el usuario debe proporcionar una implementación correcta del método hashCode. El método
* generado presupone que la clave es un objeto String.
*/
public int hashCode () {
return empNo.hashCode();
Ejemplo: manejo de la excepción de acceso a datos: ConnectionWaitTimeoutException (para la API JDBC)
Este ejemplo de código muestra cómo se especifican las condiciones bajo las cuales el servidor de aplicaciones emite la excepción ConnectionWaitTimeoutException para una aplicación JDBC.
No se puede hacer gran cosa para intentar la recuperación, si la excepción que se obtiene es ConnectionWaitTimeoutException.
public void test1() {
java.sql.Connection conn = null;
java.sql.Statement stmt = null;
java.sql.ResultSet rs = null;
try {
// Buscar el origen de datos
java.util.Properties props = new java.util.Properties();
props.put(
javax.naming.Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
ic = new javax.naming.InitialContext(props);
javax.sql.DataSource ds1 = (javax.sql.DataSource) ic.lookup(jndiString);
// Obtener la conexión.
conn = ds1.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from mytable where this = 54");
}
catch (java.sql.SQLException sqlX) {
if (sqlX instanceof com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException
|| sqlX instanceof java.sql.SQLTransientConnectionException
&& sqlX.getCause() instanceof com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException)
{
//notificar al usuario que el sistema no ha podido proporcionar una
//conexión a la base de datos. Esto ocurre normalmente cuando la
//agrupación de conexiones está llena y no hay ninguna conexión
//disponible para compartir.
}
else
{
// manejar otros problemas de base de datos.
}
}
finally {
if (rs != null)
try {
rs.close();
}
catch (java.sql.SQLException sqle1) {
}
if (stmt != null)
try {
stmt.close();
}
catch (java.sql.SQLException sqle1) {
}
if (conn != null)
try {
conn.close();
}
catch (java.sql.SQLException sqle1) {
}
}
}
Ejemplo: manejo de la excepción de acceso a datos - ConnectionWaitTimeoutException para la arquitectura de conector de Java EE (Java EE Connector Architecture)
Este ejemplo de código muestra cómo se especifican las condiciones bajo las cuales WebSphere Application Server emite la excepción ConnectionWaitTimeout para una aplicación JDBC.
En todos los casos en que se obtenga la excepción ConnectionWaitTimeout, se puede hacer muy poco por la recuperación.
El siguiente fragmento de código muestra cómo se utiliza esta excepción en JCA (Java Platform, Enterprise Edition (Java EE) Connector Architecture):
/**
* Este método realiza una sencilla comprobación de la conexión.
*/
public void testConnection()
throws javax.naming.NamingException, javax.resource.ResourceException,
com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException {
javax.resource.cci.ConnectionFactory factory = null;
javax.resource.cci.Connection conn = null;
javax.resource.cci.ConnectionMetaData metaData = null;
try {
// buscar la fábrica de conexiones
if (verbose) System.out.println("Look up the connection factory...");
try {
factory =
(javax.resource.cci.ConnectionFactory) (new InitialContext()).lookup("java:comp/env/eis/Sample");
}
catch (javax.naming.NamingException ne) {
// No se puede buscar la fábrica de conexiones.
throw ne;
}
// Obtener la conexión
if (verbose) System.out.println("Get the connection...");
conn = factory.getConnection();
// Obtener ConnectionMetaData
metaData = conn.getMetaData();
// Imprimir la información de los metadatos.
System.out.println("EISProductName" is + metaData.getEISProductName());
}
catch (com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException cwtoe) {
// Tiempo de espera de la conexión
throw cwtoe;
}
catch (javax.resource.ResourceException re) {
// Existe un error en las conexiones.
throw re;
}
finally {
if (conn != null) {
try {
conn.close();
}
catch (javax.resource.ResourceException re) {
}
}
}
}
Manejo de la excepción de acceso a datos: Error de correlación en DataStoreHelper
El servidor de aplicaciones proporciona una interfaz DataStoreHelper para correlacionar diferentes códigos de error SQL de base de datos con las excepciones adecuadas del servidor de aplicaciones.
La correlación de errores es necesaria porque varios proveedores de bases de datos pueden proporcionar distintos códigos y errores SQL que signifiquen lo mismo. Por ejemplo, la excepción de conexión inactiva tiene códigos diferentes en distintas bases de datos. Los SQLCODE de DB2 de 1015, 1034, 1036 indican que la conexión ya no está disponible debido a un problema en la base de datos temporal. Los SQLCODE de Oracle de 28, 3113, 3114, etc. indican la misma situación.
Si se correlacionan estos códigos de error con las excepciones estándar se mantiene la coherencia que permite que las aplicaciones se puedan portar entre las diferentes instalaciones del servidor de aplicaciones. El segmento de código siguiente ilustra la forma de añadir dos códigos de error en la correlación de errores:public class NewDSHelper extends GenericDataStoreHelper
{
public NewDSHelper(java.util.Properties dataStoreHelperProperties)
{
super(dataStoreHelperProperties);
java.util.Hashtable myErrorMap = null;
myErrorMap = new java.util.Hashtable();
myErrorMap.put(new Integer(-803), myDuplicateKeyException.class);
myErrorMap.put(new Integer(-1015), myStaleConnectionException.class);
myErrorMap.put("S1000", MyTableNotFoundException.class);
setUserDefinedMap(myErrorMap);
...
}
}
Una opción de configuración conocida como Modelo de detección de errores controla el modo en que se utiliza la correlación de errores. En la versión 6 y anteriores, la correlación de excepciones era la única opción disponible para el modelo de detección de errores. En la versión 7 y posteriores, también se encuentra disponible otra opción llamada Comprobación de excepciones. En el modelo de la correlación de excepciones, el servidor de aplicaciones consulta la correlación de errores y sustituye las excepciones por el tipo de excepción correspondiente listada en la correlación de errores. En el modelo de comprobación de excepciones, el servidor de aplicaciones sigue consultando la correlación de errores con fines propios pero no sustituye excepciones. Si desea continuar utilizando la correlación de excepciones, no es necesario que cambie nada. La correlación de excepciones es el modelo de detección de errores predeterminado. Si desea utilizar el modelo de comprobación de excepciones, consulte el tema "Modificación del modelo de detección de errores para utilizar el modelo de comprobación de excepciones" en los enlaces relacionados.
Conflictos entre claves foráneas y bloqueos de base de datos
Si se repiten determinados mensajes de error SQL significa que existen problemas como, por ejemplo, violaciones de la integridad referencial de la base de datos, que puede evitar utilizando la característica de agrupación de secuencias CMP (Container Managed Persistence).
Excepciones resultantes de conflictos de claves foráneas, debidos a la violación de la integridad referencial de base de datosUna política de integridad referencial (RI) de base de datos dicta las normas sobre cómo se escriben los datos en las tablas de base de datos y cómo se eliminan de éstas para mantener la coherencia relacional. Los requisitos del tiempo de ejecución para la gestión de la persistencia de los beans puede hacer que una aplicación EJB (Enterprise JavaBeans) viole las reglas RI, que pueden provocar excepciones de base de datos.
El valor de inserción o actualización de
FOREIGN KEY tabla1.nombre_de_restricción_de_claves_foráneas
no es igual a ningún valor de la clave padre de la tabla padre.
oUna
fila padre no se puede eliminar porque la relación
tabla1.nombre_de_restricción_de_claves_foráneas
no es igual a ningún valor de la clave padre de la tabla padre.
Para evitar estas excepciones, debe designar el orden en el que los beans de entidad actualicen las tablas de bases de datos relacionales mediante la definición de grupos de secuencia para los beans.
Excepciones que resultan de los puntos muertos provocados por esquemas de control de simultaneidad optimistaAdicionalmente, la agrupación de secuencias puede minimizar las excepciones de retrotracción de transacciones de los beans de entidad que se configuran para el control de simultaneidad optimista. El control de simultaneidad optimista determina que los bloqueos de base de datos se mantengan por un periodo mínimo de tiempo de modo que un número máximo de transacciones tenga acceso a los datos de modo coherente. En esta base de datos de alta disponibilidad, las transacciones simultáneas pueden intentar bloquear la misma fila de tabla y crear un punto muerto. Las excepciones resultantes pueden generar mensajes similares al que aparece a continuación (que se ha producido en un entorno que ejecute DB2):
Ejecución incorrecta
producida por un punto muerto o tiempo de espera excedido.
Utilice la característica de agrupación de secuencias para ordenar la persistencia de beans de forma que disminuya la probabilidad de la aparición de puntos muertos de base de datos.