Exceções Relativas a Acesso a Dados
Todas as persistências gerenciadas por contêiner do enterprise bean (CMP) na especificação Enterprise JavaBeans (EJB) 2.x recebem uma exceção EJB padrão quando a operação falhar. Os aplicativos Java™ Database Connectivity (JDBC) recebem uma exceção SQL padrão se qualquer operação JDBC falhar. O produto fornece exceções especiais para seu adaptador de recurso relacional (RRA) para indicar que a conexão mantida atualmente não é mais válida.
- A exceção de tempo limite de espera de conexão indica que o aplicativo aguardou o
número de segundos especificado pela configuração de tempo limite e não recebeu uma
conexão. Esta situação pode ocorrer quando o conjunto
estiver com o tamanho máximo e todas as conexões estiverem em uso por outros aplicativos
pela duração da espera. Além disso, não há conexões em uso atualmente que
o aplicativo possa compartilhar porque ou as propriedades da conexão não coincidem,
ou a conexão está em uma transação diferente.
Para uma origem de dados Versão 4.0, o objeto ConnectionWaitTimeout cria uma exceção que é instanciada da classe com.ibm.ejs.cm.pool.ConnectionWaitTimeoutException.
Para os connection factoriesJava 2 Connector (J2C), o objeto ConnectionWaitTimeout gera uma exceção de recurso da classe com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException.
Quando o modelo de detecção de erro está configurado para mapeamento de exceção, as versões posteriores de origens de dados emitem uma exceção SQL da subclasse com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException. Quando o modelo de detecção de erro está configurado para verificação de exceção, as versões posteriores de origens de dados emitem uma exceção SQL da classe java.sql.SQLTransientConnectionException com uma exceção encadeada da classe com.ibm.websphere.ce.cm.ConnectionWaitTimeoutException.
- Quando o modelo de detecção de erro está configurado para mapeamento de exceção, a exceção de conexão antiga indica que a conexão não é mais válida. Quando o modelo de detecção de erro está configurado para verificação de exceção, o driver JDBC gera uma exceção JDBC 4.0, como java.sql.SQLRecoverableException ou java.sql.SQLNonTransientConnectionException, ou o driver JDBC especifica um SQLState apropriado para indicar que a conexão não é mais válida. Consulte o tópico Conexões Antigas para obter mais informações sobre este tipo de exceção.
- As entradas são delimitadas por ; (ponto-e-vírgula).
- Cada entrada consiste de uma chave e valor, em que a chave é um código de erro (valor numérico) ou SQLState, que é o texto delimitado nas aspas.
- As chaves e valores são separados pelo sinal de igual (=).
"S1000"=;1062=com.ibm.websphere.ce.cm.DuplicateKeyException;"08004"=
com.ibm.websphere.ce.cm.StaleConnectionException
userDefinedErrorMap pode ser localizado no console administrativo selecionando a origem
de dados e configurando as propriedades customizadas.- Conexões Antigas
- Exemplo: Tratando Exceção de Acesso a Dados - Conexão Obsoleta
- Conexão Obsoleta nos Sistemas Linux
- Exemplo: Manipulando Exceções de Conexões JDBC de Servlets
- Exemplo: Manipulando Exceções de Conexões para Beans de Sessão em Transações do Banco de Dados Gerenciado por Contêiner
- Exemplo: Manipulando Exceções de Conexões para Beans de Sessão em Transações do Banco de Dados Gerenciado por Bean
- Exemplo: Manipulando Exceções de Conexões para Beans BMP em Transações do Banco de Dados Gerenciado por Contêiner
- Exemplo: Tratamento de Exceção de Acesso a Dados - ConnectionWaitTimeoutException (para a API JDBC)
- Exemplo: Manipulando a Exceção de Acesso a Dados - ConnectionWaitTimeoutException (para Java EE Connector Architecture)
- Exemplo: Tratando Exceção de Acesso a Dados - Mapeamento de Erro em DataStoreHelper
- Conflitos entre Chaves Estrangeiras e Impasses do Banco de Dados
Conexões Antigas
O produto fornece uma subclasse especial da classe java.sql.SQLException para usar o conjunto de conexões para acessar um banco de dados relacional. Esta subclasse com.ibm.websphere.ce.cm.StaleConnectionException existe em uma origem de dados do WebSphere 4.0 e na origem de dados de versão mais recente que utiliza o adaptador de recurso relacional. Essa classe é oferecida para indicar que a conexão atualmente suspensa não é mais válida.
- O aplicativo tenta obter uma conexão e falha, como quando o banco de dados não está iniciado.
- Uma conexão não é mais utilizável devido a uma falha do banco de dados. Quando um aplicativo tenta usar uma conexão obtida anteriormente, a conexão não é mais válida. Neste caso, todas as conexões em uso atualmente pelo aplicativo podem obter este erro quando tentarem usar a conexão.
- A conexão tornou-se órfã (porque o aplicativo não a utilizou no máximo duas vezes o valor da configuração de tempo limite não utilizado) e o aplicativo tenta usar a conexão órfã. Este caso se aplica somente a origens de dados da Versão 4.0.
- O aplicativo tenta usar um recurso de JDBC, como uma instrução, obtido em uma conexão stale.
- Uma conexão é fechada pelo recurso de limpeza de conexão automática da origem de
dados Versão 4.0 e não é mais utilizada. A limpeza automática de conexão é o modo padrão
no qual o gerenciamento de conexões opera. Este modo indica que no final de uma
transação o gerenciador de transação fecha todas as conexões envolvidas
nessa transação. Isso permite que o gerenciador de transação assegure que as conexões
não sejam mantidas por períodos de tempo excessivos e que o conjunto não alcance
seu número máximo de conexões prematuramente.
Uma ramificação negativa não assegura, no entanto, quando o gerenciador de transações fecha as conexões e retorna a conexão ao conjunto livre após o final da transação. Um aplicativo não pode obter uma conexão em uma transação e tentar usá-la em outra transação. Se o aplicativo tentar isso, ocorrerá uma ObjectClosedException, que, por sua vez, é um StaleConnectionException, porque a conexão já estará fechada.
- Configurando o tamanho mínimo do conjunto de conexões como 0, o conjunto de conexões é mantido vazio quando o servidor de aplicativos fica inativo por períodos prolongados. Isso ajuda a evitar que as conexões fiquem antigas devido à atividade de manutenção no lado do banco de dados.
- Configure o Tempo limite não usado conjunto de conexões para um valor menor do que o valor configurado para o tempo limite do firewall. Isso assegura que a conexão não fique antiga até o Tempo limite não usado e permite que a conexão permaneça no conjunto livre para reutilização.
- Configure o tempo de coleta do conjunto de conexões para um valor menor do que o tempo limite não usado. Quanto menor o valor, maior a frequência com que o encadeamento de manutenção do conjunto é verificado e mais preciso o cronômetro de não usado se torna. No entanto, as execuções do encadeamento de manutenção do conjunto podem degradar o desempenho.
Se estiver tentando usar a conexão órfã ou uma conexão indisponibilizada pela limpeza de conexão automática, uma exceção de conexão antiga indicará que o aplicativo tentou usar uma conexão que já foi retornada para o conjunto de conexões. Ela não indica um problema real com a conexão. Entretanto, outros casos de uma exceção de conexão danificada indicam que a conexão com o banco de dados tornou-se inválida ou danificada. Depois que uma conexão se torna stale não é possível recuperá-la, e é preciso fechar completamente a conexão em vez de retorná-la ao conjunto.
Detectando Conexões StaleQuando uma conexão ao banco de dados torna-se stale, as operações nessa conexão resultam em uma exceção SQL do driver JDBC. Como uma exceção SQL é mais propriamente uma exceção genérica, ela contém valores de código de estado e de erro que podem ser utilizados para determinar o significado da exceção. Entretanto, os significados desses estados e códigos de erro variam dependendo do fornecedor do banco de dados. O tempo de execução do conjunto de conexões mantém um mapeamento de quais códigos de erro e estado de SQL indicam uma exceção de conexão danificada para cada fornecedor de banco de dados suportado. Quando o tempo de execução do conjunto de conexões captura uma exceção SQL, ele verifica se esta exceção SQL é considerada uma exceção de conexão danificada para o servidor de banco de dados em uso.
Recuperando-se de Conexões Stale- Quando o modelo de detecção de erro está configurado para mapeamento de exceção, o servidor de aplicativos substitui a exceção emitida pelo driver JDBC por StaleConnectionException. Nesse caso, o aplicativo poderá captar uma exceção de conexão danificada.
- Quando o modelo de detecção de erro está configurado para verificação de exceção, o servidor de aplicativos ainda consulta o mapa de erros a fim de gerenciar o conjunto de conexões, mas ele não substitui a exceção. Nesse caso, o aplicativo não deverá captar uma exceção de conexão danificada.
Por causa das diferenças entre modelos de detecção de erro, o servidor de aplicativos fornece uma API que os aplicativos podem usar com qualquer dos casos para identificar conexões danificadas. A API é com.ibm.websphere.rsadapter.WSCallHelper.getDataStoreHelper(datasource).isConnectionError(sqlexception).
Os aplicativos não são obrigados a identificar explicitamente uma exceção de conexão danificada. Os aplicativos já são obrigados a capturar a java.sql.SQLException, e a exceção de conexão danificada ou a que é emitida pelo driver JDBC sempre herda dados da java.sql.SQLException. A exceção de conexão danificada, que pode resultar de qualquer método declarado para emitir SQLException, é capturada automaticamente no bloco de captura geral. Entretanto, identificar explicitamente uma exceção de conexão danificada torna possível a um aplicativo recuperar-se de conexões inválidas. Quando o código do aplicativo identifica uma exceção de conexão danificada, ele deve executar as etapas explícitas de recuperação, como tentar novamente a operação em uma nova transação e conexão.
Exemplo: Tratando Exceção de Acesso a Dados - Conexão Obsoleta
Estas amostras de códigos demonstram como endereçar de maneira programática exceções de conexões vazias para diferentes tipos de clientes de acesso a dados em diferentes cenários de transação.
Quando um aplicativo recebe uma exceção de conexão obsoleta em uma operação de banco de dados, isso indica que a conexão mantida atualmente não é mais válida. Embora seja possível obter uma exceção para uma conexão obsoleta em qualquer operação do banco de dados, o momento mais comum de ver uma exceção de conexão obsoleta emitida é depois que a conexão é recuperada pela primeira vez. Como as conexões ficam em um conjunto, uma falha do banco de dados não é detectada até a operação imediatamente seguinte à sua recuperação do conjunto, que é a primeira vez que é feita tentativa de comunicação com o banco de dados. Somente quando uma falha é detectada é que a conexão é marcada como stale. A exceção de conexão stale ocorre com menos frequência se cada método que acessa o banco de dados obtém uma nova conexão do conjunto.

Antes que o aplicativo possa obter uma nova conexão para uma nova tentativa da operação, efetue rollback da transação na qual a conexão original estava envolvida e inicie uma nova transação. Os detalhes podem ser divididos nesta seção nas seguintes duas categorias:
- Objetos operando em um contexto de transação global gerenciado por bean iniciado no mesmo método que o acesso ao banco de dados.
- Um servlet ou bean de sessão
com transações gerenciadas por bean (BMT) pode iniciar uma transação global explicitamente,
chamando begin() em um objeto javax.transaction.UserTransaction,
o qual pode ser recuperado de nomes ou do objeto EJBContext do bean.
Para efetuar commit de uma transação gerenciada por bean, o aplicativo chama commit() no
objeto UserTransaction. Para efetuar rollback da transação, o aplicativo
chama rollback(). Beans de entidade e beans de sessão não BMT não podem iniciar transações globais
explicitamente.
Se um objeto que iniciou explicitamente uma transação gerenciada por bean receber uma exceção de conexão stale em uma operação de banco de dados, feche a conexão e efetue rollback da transação. Neste ponto, o desenvolvedor do aplicativo pode decidir iniciar uma nova transação, obter uma nova conexão e tentar novamente a operação.
O fragmento de código a seguir mostra um exemplo de tratamento de exceções de conexão obsoleta neste cenário://get a userTransaction javax.transaction.UserTransaction tran = getSessionContext().getUserTransaction(); //retry indica se se deve ou não tentar novamente //numOfRetries declara quantas novas tentativas // foram tentadas boolean retry = false; int numOfRetries = 0; java.sql.Connection conn = null; java.sql.Statement stmt = null; do { try { //iniciar uma transação tran.begin(); //Supõe que um datasource já foi obtido //de 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) { // Se o erro indicar que a conexão está obsoleta, // efetuar rollback e tentar novamente a ação if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { try { tran.rollback(); } catch (java.lang.Exception e) { // lidar com exceção //na maioria dos casos, isto pode ser ignorado } if (numOfRetries < 2) { retry = true; numOfRetries++; } else { retry = false; } } else { //lidar com outra exceção de banco de dados retry = false } } finally { //sempre limpar os recursos de JDBC try { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } try { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } } } while (retry) ;
- Objetos operando em um contexto de transação global e transação não iniciada no mesmo método que o acesso ao banco de dados.
- Quando o objeto que recebe a exceção de conexão stale não tem controle
direto sobre a transação, tal como em um caso de transação gerenciada por
contêiner, o objeto deve marcar a transação para rollback e, em seguida,
indicar ao responsável pela chamada para tentar novamente a transação. Na maioria dos casos, é possível fazer isso,
criando uma exceção de aplicativo que indique para tentar novamente a operação. Entretanto, esta
ação nem sempre é permitida, e muitas vezes um método é definido somente para criar
uma determinada exceção.
Este é o caso com os métodos ejbLoad() e ejbStore()
em um enterprise bean. Os próximos dois exemplos explicam cada um desses cenários.
- Exemplo 1: O método de acesso ao banco de dados cria uma exceção do aplicativo
- Quando o método que acessa o banco de dados é livre para criar qualquer
exceção que seja necessária, a prática recomendável é capturar a exceção de conexão
stale e criar alguma exceção de aplicativo que você possa interpretar para tentar
novamente o método. O exemplo a seguir mostra um cliente EJB chamando um método
em um bean de entidade com demarcação de transação TX_REQUIRED, que significa
que o contêiner inicia uma transação global quando o insertValue() é
chamado:
public class MyEJBClient { //... outros métodos aqui... public void myEJBClientMethod() { MyEJB myEJB = myEJBHome.findByPrimaryKey("myEJB"); boolean retry = false; do { tente { 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 { //... other methods here ... public void insertValue() throws RetryableConnectionException, java.rmi.EJBException { tente { conn = ds.getConnection(); stmt = conn.createStatement(); stmt.execute("INSERT INTO my_table VALUES (1)"); } catch(java.sql.SQLException sqlX) { // Descubra se o erro indica que a conexão está obsoleta if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { getSessionContext().setRollbackOnly(); throw new RetryableConnectionException(); } else { //cuidar de outro problema de banco de dados } } finally { //sempre limpar os recursos de JDBC tente { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } tente { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } } } } //finalizar MyEJB
MyEJBClient primeiramente obtém um bean MyEJB da interface home, supondo ter sido recuperada anteriormente da JNDI (Java Naming and Directory Interface). Em seguida, chama insertValue() no bean. O método no bean obtém uma conexão e tenta inserir um valor em uma tabela. Se um dos métodos falhar com uma exceção de conexão stale, ele marcará a transação para rollbackOnly (o que força o responsável pela chamada a reverter esta transação) e cria uma nova exceção de conexão que pode ser tentada novamente, limpando os recursos antes que a exceção seja lançada. A exceção de conexão que pode ser tentada novamente é simplesmente uma exceção definida pelo aplicativo que diz ao responsável pela chamada para tentar novamente o método. O responsável pela chamada monitora a exceção de conexão que pode ser tentada novamente e, se ela for capturada, tenta novamente o método. Neste exemplo, como o contêiner está iniciando e finalizando a transação, nenhum gerenciamento da transação você deve no cliente ou no servidor. O cliente, é claro, poderia iniciar uma transação gerenciada por bean e o comportamento ainda seria o mesmo, desde que o cliente também efetuasse commit ou rollback da transação.
- Exemplo 2: O método de acesso ao banco de dados cria uma exceção onlyRemote ou uma exceção EJB
- Nem todos os métodos têm permissão para lançar exceções definidas pelo aplicativo. Se você usar persistência gerenciada por bean (BMP), use os métodos ejbLoad() e ejbStore()
para armazenar o estado do bean. As únicas exceções emitidas a partir desses
métodos são a exceção java.rmi.Remote ou a exceção javax.ejb.EJB; portanto,
você não pode usar algo semelhante ao exemplo anterior.Se você usar CMP (container-managed persistence), o contêiner gerenciará a persistência de bean e será o contêiner que reconhece a exceção de conexão stale. Se uma conexão stale for detectada, quando a exceção for retornada ao cliente, ela será simplesmente uma exceção remota e, portanto, um simples bloco catch não é suficiente. Existe uma maneira de determinar se a causa raiz de uma exceção remota é uma exceção de conexão stale. Quando uma exceção remota é criada para agrupar outra exceção, a exceção original, geralmente, é retida. Todas as instâncias de exceção remota têm uma propriedade de detalhe, que é do tipo java.lang.Throwable. Com este detalhe, é possível rastrear de volta até a exceção original e, se ela for uma exceção de conexão stale, tentar novamente a transação. Na verdade, quando uma dessas exceções remotas flui de uma API da Java Virtual Machine para a seguinte, o detalhe é perdido, de modo que é melhor iniciar uma transação no mesmo servidor em que ocorre o acesso ao banco de dados. Por este motivo, o exemplo a seguir mostra um bean de entidade acessado por um bean de sessão com demarcação de transação gerenciada por bean.
public class MySessionBean extends javax.ejb.SessionBean { ... outros métodos aqui ... public void mySessionBMTMethod() throws java.rmi.EJBException { javax.transaction.UserTransaction tran = getSessionContext().getUserTransaction(); boolean retry = false; do { try { retry = false; tran.begin(); // faz com que ejbLoad() seja chamado myBMPBean.myMethod(); // faz com que ejbStore() seja chamado tran.commit(); } catch(java.rmi.EJBException re) { tente { tran.rollback(); } catch(Exception e) { //pode ignorar } if (causedByStaleConnection(re)) retry = true; else throw re; } catch(Exception e) { // cuidar de algum outro problema } finally { //sempre limpar os recursos de JDBC tente { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } tente { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } } } while (retry); } public boolean causedByStaleConnection(java.rmi.EJBException re) { // Procurar erros na cadeia de exceção // que indiquem uma conexão obsoleta for (Throwable t = re; t != null; t = t.getCause()) if (t instanceof RetryableConnectionException) return true; // Não descoberto estar obsoleta return false; } } public class MyEntityBean extends javax.ejb.EntityBean { ... outros métodos aqui ... public void ejbStore() throws java.rmi.EJBException { tente { conn = ds.getConnection(); stmt = conn.createStatement(); stmt.execute("UPDATE my_table SET value=1 WHERE primaryKey=" + myPrimaryKey); } catch(java.sql.SQLException sqlX) { // Descubra se o erro indica que a conexão está obsoleta if (com.ibm.websphere.rsadapter.WSCallHelper .getDataStoreHelper(ds) .isConnectionError(sqlX)) { // efetuar rollback da transação quando o método retornar getEntityContext().setRollbackOnly(); throw new java.rmi.EJBException( "Exception occurred in ejbStore", new RetryableConnectionException(sqlX)); } else { // cuidar de algum outro problema } } finally { //sempre limpar os recursos de JDBC tente { if (stmt != null) stmt.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } tente { if (conn != null) conn.close(); } catch (java.sql.SQLException sqle) { //em geral pode ignorar } } } }
Em mySessionBMTMethod() do exemplo anterior:- O bean de sessão primeiro recupera um objeto UserTransaction do contexto da sessão e, em seguida, inicia uma transação global.
- A seguir, ele chama um método no bean de entidade, o qual chama o método ejbLoad(). Se ejbLoad() executar com êxito, o cliente efetuará commit da transação fazendo com que o método ejbStore() seja chamado.
- Em ejbStore(), o bean de entidade obtém uma conexão e grava seu estado no banco de dados; se a conexão recuperada estiver obsoleta, a transação será marcada como rollbackOnly e uma nova exceção EJBException que agrupa RetryableConnectionException será lançada. Esta exceção é, então, capturada pelo cliente, o qual limpa os recursos de JDBC, efetua rollback da transação e chama causedByStaleConnection(), que determina se uma exceção de conexão stale está localizada em algum lugar na exceção.
- Se o método retornar true, o sinalizador de nova tentativa será definido e a transação será tentada novamente; caso contrário, a exceção será reemitida para o responsável pela chamada.
- O método causedByStaleConnection() procura na cadeia de atributos de detalhe para localizar a exceção original. Múltiplos agrupamentos de exceções podem ocorrer até que a exceção finalmente retorne para o cliente, por isso o método continua procurando até que encontre a exceção de conexão obsoleta e true seja retornado; caso contrário, não há exceção de conexão obsoleta na lista e false é retornado.
- Se estiver referenciando um bean do CMP em vez do bean BMP, o bean de sessão será o mesmo. O método ejbStore() do bean CMP estaria mais provavelmente vazio e o contêiner após chamá-lo persistira o bean com o código gerado.
- Se uma exceção de conexão stale ocorrer durante a persistência, ela será agrupada com uma exceção remota e retornada ao responsável pela chamada. O método causedByStaleConnection() procuraria novamente na cadeia de exceções e localizaria a exceção raiz que seria a exceção de conexão stale.
- Objetos operando em um contexto de transação local
- Quando uma operação de
banco de dados ocorre fora de um contexto de transação global, uma transação local
é iniciada implicitamente pelo contêiner.
Isso inclui servlets ou JSPs que não
iniciam transações com a interface UserTransaction, bem como beans corporativos
em execução em contextos de transação não especificados. Como ocorre com transações
globais, é preciso efetuar rollback na transação local antes que a operação seja
tentada novamente. Nestes casos, a contenção da transação local, em geral, finaliza
quando o método de negócio é finalizado. A única exceção é se você estiver utilizando sessões de
atividade. Neste caso, a sessão de atividade deve finalizar antes de tentar
obter uma nova conexão.
Quando a transação local ocorre em um enterprise bean em execução em um contexto de transação não especificado, o objeto cliente do enterprise bean, fora da contenção da transação local, poderia usar o método descrito no tópico anterior para tentar novamente a transação. Contudo, quando a contenção da transação local ocorre como parte de um servlet ou arquivo JSP, não existe um objeto de cliente disponível para tentar novamente a operação. Por este motivo, recomenda-se evitar operações de banco de dados em servlets e arquivos JSP a menos que sejam parte de uma transação de usuário.
Conexão Obsoleta nos Sistemas Linux
Você deve configurar um loopback para acessar os bancos de dados DB2 a partir do servidor de aplicativos em uma plataforma Linux.
- Utilizando o driver JDBC Tipo 2 do DB2 Universal para conectar-se a um banco de dados DB2 local
- Utilizando o driver JDBC Tipo 2 do DB2 Universal para acessar o DB2 para z/OS por meio de uma instalação do DB2 Connect na mesma máquina que o servidor de aplicativos. O problema ocorrerá somente se o DB2 Connect restringir os clientes locais da execução em um agente. (Isto é se a configuração the DB2_IN_APP_PROCESS não for o valor padrão, ou se a configuração for Sim. Configure o valor para Não para corrigir o problema e evite executar o procedimento a seguir.)
'71' -SQLCC_ERR_CONN_CLOSED_BY_PARTNER and 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 //Se você conectar-se ao WASAlias, a conexão será por meio de auto-retorno; //Se você conectar-se ao WAS, será uma conexão "normal". db2 catalog db WASAlias as WAS at node RHOST
Exemplo: Manipulando Exceções de Conexões JDBC de Servlets
A amostra de código a seguir demonstra como configurar as propriedades de gerenciamento de transação e de conexão, tais como tentativas de repetição, para endereçar exceções de conexões vazias dentro de uma transação JDBC de servlet.
- inicializa um servlet
- pesquisa uma origem de dados
- especifica as mensagens de erro, tentativas de repetição de conexão e requisitos de recuperação de transação
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQUENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// Importar pacotes JDBC e pacotes do serviço de nomes.
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 o servlet quando ele é carregado pela primeira vez *
// * Obter informações do arquivo de propriedades e pesquisar o *
// * Objeto DataSource de JNDI para melhorar o desempenho dos *
// * métodos de serviço do servlet. *
// ****************************************************************
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
getDS();
}
// ****************************************************************
// * Executar a pesquisa de JNDI para os objetos DataSource e *
// * User Transaction. *
// * Este método é chamado de init() e do método de *
// * serviço do DataSource é 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);
// Executar uma pesquisa no serviço de nomes para obter o 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 ao pedido GET do usuário *
// ****************************************************************
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
// Defina retryCount como o número de vezes que você gostaria de tentar novamente após uma
// exceção de conexão antiga
int retryCount = 5;
// Se o código do Banco de Dados processar com êxito, definiremos error = false
boolean error = true;
do
{
tente
{
//Iniciar uma nova Transação
ut.begin();
// Obter um objeto de conexão conn utilizando a fábrica DataSource.
conn = ds.getConnection();
// Executar consulta de BD utilizando codificação JDBC padrão.
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 como false para indicar a conclusão com êxito do trabalho do banco de dados
error=false;
}
catch (SQLException sqlX)
{
// Determinar se o pedido de conexão esgotou o tempo limite.
// Este código funciona independentemente de qual modelo de detecção
// de erro é utilizado. Se o mapeamento de exceção estiver ativado,
// será necessário procurar a exceção ConnectionWaitTimeoutException.
// Se a verificação de exceção estiver ativada, procure
// SQLTransientConnectionException com uma
// ConnectionWaitTimeoutException em cadeia.
if ( sqlX instanceof ConnectionWaitTimeoutException
|| sqlX instanceof SQLTransientConnectionException
&& sqlX.getCause() instanceof ConnectionWaitTimeoutException)
{
// Esta exceção é lançada se não for possível obter uma conexão do
// conjunto dentro de um período de tempo configurável. Ocorrências frequentes
// desta exceção indicam um conjunto de conexões ajustado incorretamente
System.out.println("Exceção de tempo limite de espera de conexão ao obter conexão ou
process SQL: " + c.getMessage());
//Em geral, não queremos tentar novamente após esta exceção, portanto, defina a contagem de novas tentativas como 0
//e reverter a transação
tente
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Lançada para indicar que não é permitido ao encadeamento efetuar rollback da transação.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise) {
//Lançada se o encadeamento atual não estiver associado a uma transação.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
else if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta exceção indica que a conexão ao banco de dados não é mais válida.
//Reverter a transação e depois repetir várias vezes para tentar obter uma conexão
//válida, exiba uma mensagem de erro se a conexão ainda não puder ser obtida.
System.out.println("Connection is stale: " + sc.getMessage());
tente
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Lançada para indicar que não é permitido ao encadeamento efetuar rollback da transação.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise) {
//Lançada se o encadeamento atual não estiver associado a uma transação.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
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("Exceção SQL durante get connection ou SQL de processo: " + sq.getMessage());
//Em geral, não queremos tentar novamente após esta exceção, portanto, defina a contagem de novas tentativas como 0
//e efetue rollback da transação
tente
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Lançada para indicar que não é permitido ao encadeamento efetuar rollback da transação.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise) {
//Lançada se o encadeamento atual não estiver associado a uma transação.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
}
catch (NotSupportedException nse) {
//Lançada pelo método begin de UserTransaction se o encadeamento já estiver associado a uma
//transação e a implementação do Transaction Manager não suportam transações
//aninhadas.
System.out.println("NotSupportedException on User Transaction begin: " + nse.getMessage());
}
catch (SystemException se) {
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
System.out.println("SystemException in User Transaction: "+ se.getMessage());
}
catch (Exception e)
{
System.out.println("Exception in get connection or process SQL: " + e.getMessage());
//Em geral, não queremos tentar novamente após esta exceção, portanto, defina a contagem de novas tentativas como 5
//e reverter a transação
tente
{
ut.setRollbackOnly();
}
catch (SecurityException se)
{
//Lançada para indicar que não é permitido ao encadeamento efetuar rollback da transação.
System.out.println("Security Exception setting rollback only!" + se.getMessage());
}
catch (IllegalStateException ise) {
//Lançada se o encadeamento atual não estiver associado a uma transação.
System.out.println("Illegal State Exception setting rollback only!" + ise.getMessage());
}
catch (SystemException sye)
{
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
System.out.println("System Exception setting rollback only!" + sye.getMessage());
}
retryCount=0;
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um fechamento
// apropriado em todos os casos. Fechar a conexão não fecha uma conexão real,
// mas a libera de volta ao conjunto para reutilização.
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)
{
tente
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
tente
{
ut.commit();
}
catch (RollbackException re) {
//Lançada para indicar que foi efetuado rollback da transação em vez de commit.
System.out.println("User Transaction Rolled back!" + re.getMessage());
}
catch (SecurityException se)
{
//Lançada para indicar que não é permitido ao encadeamento efetuar commit da transação.
System.out.println("Security Exception thrown on transaction commit: " + se.getMessage());
}
catch (IllegalStateException ise) {
//Lançada se o encadeamento atual não estiver associado a uma transação.
System.out.println("Illegal State Exception thrown on transaction commit: " + ise.getMessage());
}
catch (SystemException sye)
{
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
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 e retornar resposta HTML, impedir o conteúdo dinâmico de ser armazenado em cache
// cache nos navegadores.
res.setContentType("text/html");
res.setHeader("Pragma", "no-cache");
res.setHeader("Cache-Control", "no-cache");
res.setDateHeader("Expires", 0);
tente
{
ServletOutputStream out = res.getOutputStream();
out.println("<HTML>");
out.println("<HEAD><TITLE>" + title + "</TITLE></HEAD>");
out.println("<BODY>");
if (error==true)
{
out.println("<H1>There was an error processing this request.</H1>" +
"Please try the request again, or contact " +
" the <a href='mailto:sysadmin@my.com'>System Administrator</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());
}
}
}
Exemplo: Manipulando Exceções de Conexões para Beans de Sessão em Transações do Banco de Dados Gerenciado por Contêiner
A amostra de código a seguir demonstra como recuperar as transações e emitir exceções para o cliente bean, em casos de exceções de conexões vazias.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE 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 é projetado para demonstrar Conexões de Banco de Dados em um
* Bean de Sessão de Transação Gerenciada por Contêiner. Seu atributo de transação *
* deve ser definido como TX_REQUIRED ou 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 chama o método getDS, o qual faz a pesquisa de JNDI para o DataSource.
//* Como a pesquisa do DataSource está em um método separado, também podemos chamá-la a partir do
//* método getEmployees no caso em que o campo de DataSource é nulo.
//************************************************************************************
public void ejbActivate() throws java.rmi.EJBException {
getDS();
}
/**
* método ejbCreate
* @exception javax.ejb.CreateException
* @exception java.rmi.EJBException
*/
public void ejbCreate() throws javax.ejb.CreateException, java.rmi.EJBException {}
/**
* método ejbPassivate
* @exception java.rmi.EJBException
*/
public void ejbPassivate() throws java.rmi.EJBException {}
/**
* método ejbRemove
* @exception java.rmi.EJBException
*/
public void ejbRemove() throws java.rmi.EJBException {}
//************************************************************************************
//* O método getEmployees executa a consulta ao banco de dados para recuperar os funcionários.
//* O método getDS é chamado somente se a variável DataSource for nula.
//* Como este bean de sessão utiliza Transações Gerenciadas por Contêiner, ele não pode tentar novamente a
//* transação em uma StaleConnectionException. Contudo, ele pode lançar uma exceção para
//* seu cliente indicando que a operação pode ser tentada novamente.
//************************************************************************************
public Vector getEmployees() throws ConnectionWaitTimeoutException, SQLException,
RetryableConnectionException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
if (ds == null) getDS();
tente
{
// Obter um objeto de conexão conn utilizando a fábrica DataSource.
conn = ds.getConnection();
// Executar consulta de BD utilizando codificação JDBC padrão.
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 se a conexão está vencida
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta exceção indica que a conexão ao banco de dados não é mais válida.
// Reverter a transação e lançar uma exceção para o cliente indicando que ele
// pode tentar novamente a transação, caso deseje.
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 se o pedido de conexão esgotou o tempo limite.
else if ( sqlX instanceof ConnectionWaitTimeoutException
|| sqlX instanceof SQLTransientConnectionException
&& sqlX.getCause() instanceof ConnectionWaitTimeoutException)
{
// Esta exceção é lançada se não for possível obter uma conexão do
// conjunto dentro de um período de tempo configurável. Ocorrências frequentes
// desta exceção indicam um conjunto de conexões ajustado incorretamente
System.out.println("Connection Wait Timeout Exception during get connection or process SQL: " +
sqlX.getMessage());
throw sqlX instanceof ConnectionWaitTimeoutException ?
sqlX :
(ConnectionWaitTimeoutException) sqlX.getCause();
}
else
{
//Lançar uma exceção remota reverterá automaticamente a transação gerenciada
//por contêiner
System.out.println("Exceção SQL durante get connection ou SQL de processo: " +
sqlX.getMessage());
throw sqlX;
}
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um fechamento
// apropriado em todos os casos. Fechar a conexão não fecha uma conexão real,
// mas a libera de volta ao conjunto para reutilização.
if (rs != null)
{
tente
{
rs.close();
}
catch (Exception e)
{
System.out.println("Close Resultset Exception: " +
e.getMessage());
}
}
if (stmt != null)
{
tente
{
stmt.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " +
e.getMessage());
}
}
if (conn != null)
{
tente
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
return employeeList;
}
/**
* método getSessionContext
* @return javax.ejb.SessionContext
*/
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
//************************************************************************************
//* O método getDS executa a consulta JNDI para obter a origem de dados.
//* Este método será chamado de ejbActivate, e de getEmployees, se o objeto de origem de dados
//* for 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);
// Executar uma pesquisa no serviço de nomes para obter o objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
}
catch (Exception e) {
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* método setSessionContext
* @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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta é uma interface Home para o Bean de Sessão
*/
public interface ShowEmployeesCMTHome extends javax.ejb.EJBHome {
/**
* método create para um bean de sessão
* @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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* This is an Enterprise Java Bean Remote Interface
*/
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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Exceção indicando que a operação pode ser tentada novamente
* Data de criação: (2/4/2001 10:48:08)
* @author: Administrador
*/
public class RetryableConnectionException extends Exception {
/**
* construtor RetryableConnectionException.
*/
public RetryableConnectionException() {
super();
}
/**
* construtor RetryableConnectionException.
* @param s java.lang.String
*/
public RetryableConnectionException(String s) {
super(s);
}
}
Exemplo: Manipulando Exceções de Conexões para Beans de Sessão em Transações do Banco de Dados Gerenciado por Bean
A amostra de código a seguir demonstra suas opções para exceções de conexões vazias. É possível configurar diferentes parâmetros de gerenciamento de transação e de conexão, tal como o número de tentativas de repetições de operações e o intervalo de tempo limite de conexão.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE 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 é projetado para demonstrar Conexões com o Banco de Dados em um *
* Bean de Sessão de Transação Gerenciada por Bean. Seu atributo de transação *
* deve ser configurado como 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 chama o método getDS, o qual faz a pesquisa de JNDI para o DataSource
//* Como a pesquisa do DataSource está em um método separado, também podemos chamá-la a partir do
//* método getEmployees no caso em que o campo de DataSource é nulo.
//************************************************************************************
public void ejbActivate() throws java.rmi.EJBException {
getDS();
}
/**
* método ejbCreate
* @exception javax.ejb.CreateException
* @exception java.rmi.EJBException
*/
public void ejbCreate() throws javax.ejb.CreateException, java.rmi.EJBException {}
/**
* método ejbPassivate
* @exception java.rmi.EJBException
*/
public void ejbPassivate() throws java.rmi.EJBException {}
/**
* método ejbRemove
* @exception java.rmi.EJBException
*/
public void ejbRemove() throws java.rmi.EJBException {}
//************************************************************************************
//* O método getEmployees executa a consulta ao banco de dados para recuperar os funcionários.
//* O método getDS é chamado somente se as variáveis DataSource ou userTran forem nulas.
//* Se uma conexão vencida ocorrer, o bean tentará a transação 5 vezes;
//* em seguida, lança uma EJBException.
//************************************************************************************
public Vector getEmployees() throws EJBException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Vector employeeList = new Vector();
// Defina retryCount como o número de vezes que você gostaria de tentar novamente após uma
// conexão vencida
int retryCount = 5;
// Se o código do Banco de Dados processar com êxito, definiremos error = false
boolean error = true;
if (ds == null || userTran == null) getDS();
do
{
tente
{
//bloco try/catch para trabalho de UserTransaction
//Iniciar a transação
userTran.begin();
tente
{
//bloco try/catch para trabalho de banco de dados
//Obter conn de um objeto de Conexão utilizando a fábrica de DataSource.
conn = ds.getConnection();
// Executar consulta de BD utilizando codificação JDBC padrão.
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 como false, pois todas as operações do banco de dados concluíram com êxito
error = false;
}
catch (SQLException sqlX)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(sqlX))
{
// Esta exceção indica que a conexão ao banco de dados não é mais válida.
// Efetue rollback da transação e lançe uma exceção para o cliente indicando que ele
// pode tentar novamente a transação, caso deseje.
System.out.println("Stale connection: " +
se.getMessage());
userTran.rollback();
if (--retryCount == 0)
{
//Se já tivermos tentato o número solicitado de vezes, lançe uma 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 exceção é lançada se não for possível obter uma conexão do
// conjunto dentro de um período de tempo configurável. Ocorrências frequentes
// desta exceção indicam um conjunto de conexões ajustado incorretamente
System.out.println("Connection request timed out: " +
sqlX.getMessage());
userTran.rollback();
throw new EJBException("Transaction failure: " + sqlX.getMessage());
}
else
{
// This catch handles all other SQL Exceptions
System.out.println("Exceção SQL durante get connection ou SQL de processo: " +
sqlX.getMessage());
userTran.rollback();
throw new EJBException("Transaction failure: " + sqlX.getMessage());
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um fechamento
// apropriado em todos os casos. Fechar a conexão não fecha uma conexão real,
// mas a libera de volta ao conjunto para reutilização.
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) {
//O trabalho do banco de dados concluiu com êxito, efetuar commit da transação
userTran.commit();
}
//Capturar exceções UserTransaction
}
catch (NotSupportedException nse) {
//Lançada pelo método begin de UserTransaction se o encadeamento já estiver associado a uma
//transação e a implementação do Gerenciador de Transação não suportar transações aninhadas.
System.out.println("NotSupportedException on User Transaction begin: " +
nse.getMessage());
throw new EJBException("Transaction failure: " + nse.getMessage());
}
catch (RollbackException re) {
//Lançada para indicar que foi efetuado rollback da transação em vez de commit.
System.out.println("User Transaction Rolled back!" + re.getMessage());
throw new EJBException("Transaction failure: " + re.getMessage());
}
catch (SystemException se) {
//Lançada se o gerenciador de transações encontrar uma condição de erro inesperada
System.out.println("SystemException in User Transaction: "+ se.getMessage());
throw new EJBException("Transaction failure: " + se.getMessage());
}
catch (Exception e) {
//tratar de quaisquer Exceções genéricas ou inesperadas
System.out.println("Exception in User Transaction: " + e.getMessage());
throw new EJBException("Transaction failure: " + e.getMessage());
}
}
while (error);
return employeeList;
}
/**
* comentário do método getSessionContext
* @return javax.ejb.SessionContext
*/
public javax.ejb.SessionContext getSessionContext() {
return mySessionCtx;
}
//************************************************************************************
//* O método getDS executa a pesquisa JNDI para o DataSource.
//* Este método é chamado de ejbActivate, e de getEmployees se o objeto DataSource
//* object is null.
//************************************************************************************
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Executar uma pesquisa no serviço de nomes para obter o objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
//Criar o objeto UserTransaction
userTran = mySessionCtx.getUserTransaction();
}
catch (Exception e) {
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* método setSessionContext
* @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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta é uma interface Home para o Bean de Sessão
*/
public interface ShowEmployeesBMTHome extends javax.ejb.EJBHome {
/**
* método create para um bean de sessão
* @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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* This is an Enterprise Java Bean Remote Interface
*/
public interface ShowEmployeesBMT extends javax.ejb.EJBObject {
/**
*
* @return java.util.Vector
*/
java.util.Vector getEmployees() throws java.rmi.RemoteException, javax.ejb.EJBException;
}
Exemplo: Manipulando Exceções de Conexões para Beans BMP em Transações do Banco de Dados Gerenciado por Contêiner
A amostra de código a seguir demonstra como recuperar as transações e emitir exceções para o cliente bean, em casos de exceções de conexões vazias.
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2005,2008
// Todos os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE 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 é uma classe de Bean de Entidade com 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;
/**
* método ejbActivate
* ejbActivate chama getDS(), que desempenha a
* pesquisa JNDI para o datasource.
*/
public void ejbActivate() {
getDS();
}
/**
* método ejbCreate para um bean de entidade BMP
* @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 exceção indica que a conexão ao banco de dados não é mais válida.
// Efetue rollback da transação e lançe uma exceção para o cliente indicando que ele
// pode tentar novamente a transação, caso deseje.
System.out.println("Connection is stale: " + se.getMessage());
throw new CreateException(se.getMessage());
}
else
{
System.out.println("Exceção SQL durante get connection ou SQL de processo: " +
se.getMessage());
throw new CreateException(se.getMessage());
}
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um fechamento
// apropriado em todos os casos. O fechamento da conexão não fecha uma conexão real,
// mas a libera de volta ao conjunto para reutilização.
if (ps != null)
{
tente
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null)
{
tente
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
return new EmployeeBMPKey(this.empNo);
}
/**
* método ejbFindByPrimaryKey
* @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;
}
/**
* método ejbLoad
*/
public void ejbLoad() {
try {
EmployeeBMPKey pk = (EmployeeBMPKey) entityContext.getPrimaryKey();
loadByEmpNo(pk.empNo);
} catch (FinderException fe) {
throw new EJBException("Não é possível carregar o estado do Funcionário a partir do banco de dados.");
}
}
/**
* método ejbPassivate
*/
public void ejbPassivate() {}
/**
* método ejbPostCreate para um bean de entidade BMP
* @param key WebSphereSamples.ConnPool.EmployeeBMPKey
*/
public void ejbPostCreate(String empNo, String firstName, String lastName, String middleInit,
int edLevel) {}
/**
* método ejbRemove
* @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;
tente
{
con = ds.getConnection();
ps = con.prepareStatement(sql);
ps.setString(1, empNo);
if (ps.executeUpdate() != 1) {
throw new EJBException("Não é possível remover o funcionário: " + empNo);
}
}
catch (SQLException se)
{
if (WSCallHelper.getDataStoreHelper(ds).isConnectionError(se))
{
// Esta exceção indica que a conexão ao banco de dados não é mais válida.
// Efetue rollback da transação e lançe uma exceção para o cliente indicando que ele
// pode tentar novamente a transação, caso deseje.
System.out.println("Connection is stale: " + se.getMessage());
throw new EJBException(se.getMessage());
}
else
{
System.out.println("Exceção SQL durante get connection ou SQL de processo: " +
se.getMessage());
throw new EJBException(se.getMessage());
}
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um fechamento
// apropriado em todos os casos. O fechamento da conexão não fecha uma conexão real,
// mas a libera de volta ao conjunto para reutilização.
if (ps != null)
{
tente
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (con != null)
{
tente
{
con.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
}
/**
* Obter o edLevel do funcionário
* Data de criação: (20/4/2001 15:46:22)
* @return int
*/
public int getEdLevel() {
return edLevel;
}
/**
* método getEntityContext
* @return javax.ejb.EntityContext
*/
public javax.ejb.EntityContext getEntityContext() {
return entityContext;
}
/**
* Obter o primeiro nome do funcionário
* Data de criação: (19/4/2001 13:34:47)
* @return java.lang.String
*/
public java.lang.String getFirstName() {
return firstName;
}
/**
* Obter o sobrenome do funcionário
* Data de criação: (19/4/2001 13:35:41)
* @return java.lang.String
*/
public java.lang.String getLastName() {
return lastName;
}
/**
* obter a inicial intermediária do funcionário
* Data de criação: (19/4/2001 13:36:15)
* @return char
*/
public String getMiddleInit() {
return middleInit;
}
/**
* Pesquisar a DataSource de JNDI
* Data de criação: (19/4/2001 15:28:15)
*/
private void getDS() {
try {
Hashtable parms = new Hashtable();
parms.put(Context.INITIAL_CONTEXT_FACTORY,
com.ibm.websphere.naming.WsnInitialContextFactory);
InitialContext ctx = new InitialContext(parms);
// Executar uma pesquisa no serviço de nomes para obter o objeto DataSource.
ds = (DataSource)ctx.lookup("java:comp/env/jdbc/SampleDB");
}
catch (Exception e) {
System.out.println("Naming service exception: " + e.getMessage());
e.printStackTrace();
}
}
/**
* Carregar o funcionário do banco de dados
* Data de criação: (19/4/2001 15:44:07)
* @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();
tente
{
// Obter um objeto de conexão conn utilizando a fábrica DataSource.
conn = ds.getConnection();
// Executar consulta de BD utilizando codificação JDBC padrão.
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 exceção indica que a conexão ao banco de dados não é mais válida.
// Reverter a transação e lançar uma exceção para o cliente indicando que ele
// pode tentar novamente a transação, caso deseje.
System.out.println("Connection is stale: " + se.getMessage());
throw new FinderException(se.getMessage());
}
else
{
System.out.println("Exceção SQL durante get connection ou SQL de processo: " +
se.getMessage());
throw new FinderException(se.getMessage());
}
}
finally
{
// Sempre feche a conexão em uma instrução finally para assegurar um
// fechamento apropriado em todos os casos. O fechamento da conexão não
// fecha uma conexão real, mas libera-a de volta ao conjunto
// para ser reutilizada.
if (rs != null)
{
tente
{
rs.close();
}
catch (Exception e)
{
System.out.println("Close Resultset Exception: " + e.getMessage());
}
}
if (ps != null)
{
tente
{
ps.close();
}
catch (Exception e)
{
System.out.println("Close Statement Exception: " + e.getMessage());
}
}
if (conn != null)
{
tente
{
conn.close();
}
catch (Exception e)
{
System.out.println("Close connection exception: " + e.getMessage());
}
}
}
}
/**
* definir o nível de educação de um funcionário
* Data de criação: (20/4/2001 15:46:22)
* @param newEdLevel int
*/
public void setEdLevel(int newEdLevel) {
edLevel = newEdLevel;
}
/**
* método setEntityContext
* @param ctx javax.ejb.EntityContext
*/
public void setEntityContext(javax.ejb.EntityContext ctx) {
entityContext = ctx;
}
/**
* definir o primeiro nome do funcionário
* Data de criação: (19/4/2001 13:34:47)
* @param newFirstName java.lang.String
*/
public void setFirstName(java.lang.String newFirstName) {
firstName = newFirstName;
}
/**
* definir o sobrenome do funcionário
* Data de criação: (19/4/2001 13:35:41)
* @param newLastName java.lang.String
*/
public void setLastName(java.lang.String newLastName) {
lastName = newLastName;
}
/**
* definir a inicial intermediária do funcionário
* Data de criação: (19/4/2001 13:36:15)
* @param newMiddleInit char
*/
public void setMiddleInit(String newMiddleInit) {
middleInit = newMiddleInit;
}
/**
* método unsetEntityContext
*/
public void unsetEntityContext() {
entityContext = null;
}
}
//===================START_PROLOG======================================
//
// 5630-A23, 5630-A22,
// (C) COPYRIGHT International Business Machines Corp. 2002,2008
// Todos os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* This is an Enterprise Java Bean Remote Interface
*/
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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* This is an Enterprise Java Bean Remote Interface
*/
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 os Direitos Reservados
// Materiais Licenciados - Propriedade da IBM
// Direitos Restritos de Usuários do Governo dos EUA - Uso, duplicação ou
// divulgação restritos pelo documento GSA ADP Schedule Contract com a IBM Corporation.
//
// A IBM SE EXIME DE TODAS AS GARANTIAS EM RELAÇÃO A ESTE SOFTWARE, INCLUINDO
// TODAS AS GARANTIAS IMPLÍCITAS DE MERCADO E ADEQUAÇÃO A UM DETERMINADO
// PROPÓSITO. EM NENHUM CASO A IBM PODE SER RESPONSABILIZADA POR NENHUM DANO ESPECÍFICO, INDIRETO OU
// CONSEQÜENCIAL OU POR QUALQUER OUTRO DANO RESULTANTE DE PERDA DE
// USO, DADOS OU LUCROS, SEJA EM UMA AÇÃO DE CONTRATO, NEGLIGÊNCIA OU
// OUTRA AÇÃO TORTUOSA, RESULTANTE DE OU EM CONEXÃO COM O USO
// OU DESEMPENHO DESTE SOFTWARE.
//
//===================END_PROLOG========================================
package WebSphereSamples.ConnPool;
/**
* Esta é uma Classe de Chave Primária para o Bean de Entidade
**/
public class EmployeeBMPKey implements java.io.Serializable {
public String empNo;
final static long serialVersionUID = 3206093459760846163L;
/**
* construtor EmployeeBMPKey()
*/
public EmployeeBMPKey() {
}
/**
* Construtor EmployeeBMPKey(String key)
*/
public EmployeeBMPKey(String key) {
empNo = key;
}
/**
* método equals
* - o usuário precisa fornecer uma implementação apropriada para o método equal. O método gerado
* supõe que a chave é um objeto String.
*/
public boolean equals (Object o) {
if (o instanceof EmployeeBMPKey)
return empNo.equals(((EmployeeBMPKey)o).empNo);
else
return false;
}
/**
* método hashCode
* - o usuário precisa fornecer uma implementação apropriada para o método hashCode. O método gerado
* supõe que a chave é um objeto String.
*/
public int hashCode () {
return empNo.hashCode();
Exemplo: Tratamento de Exceção de Acesso a Dados - ConnectionWaitTimeoutException (para a API JDBC)
Esta amostra de código demonstra como especificar as condições nas quais o servidor de aplicativos emite a ConnectionWaitTimeoutException para um aplicativo JDBC.
Em todos os casos em que a ConnectionWaitTimeoutException é capturada, é muito pouco o que pode ser feito para recuperação.
public void test1() {
java.sql.Connection conn = null;
java.sql.Statement stmt = null;
java.sql.ResultSet rs = null;
try {
// Procurar o datasource
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);
// Obter a Conexão.
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 ao usuário que o sistema não pôde fornecer uma
//conexão ao banco de dados. Isto, em geral, ocorre quando o
//conjunto de conexões está cheio e não existe uma conexão
//disponível para compartilhar.
}
else
{
// handle other database problems.
}
}
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) {
}
}
}
Exemplo: Manipulando a Exceção de Acesso a Dados - ConnectionWaitTimeoutException para Java EE Connector Architecture
Essa amostra de código demonstra como especificar as condições sob as quais o WebSphere Application Server emite a exceção ConnectionWaitTimeout para um aplicativo JCA.
Em todos os casos em que a ConnectionWaitTimeout é capturada, é muito pouco o que pode ser feito para recuperação.
O fragmento de código a seguir mostra como usar esta exceção no Java Platform, Enterprise Edition (Java EE) Connector Architecture (JCA):
/**
* Este método faz um teste simples da Conexão.
*/
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 {
// pesquisar a Connection Factory
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) {
// A fábrica de conexão não pode ser pesquisada.
throw ne;
}
// Obter a conexão
if (verbose) System.out.println("Get the connection...");
conn = factory.getConnection();
// Obter ConnectionMetaData
metaData = conn.getMetaData();
// Print out the metadata Information.
System.out.println("EISProductName" is + metaData.getEISProductName());
}
catch (com.ibm.websphere.ce.j2c.ConnectionWaitTimeoutException cwtoe) {
// Tempo Limite de Espera da Conexão
throw cwtoe;
}
catch (javax.resource.ResourceException re) {
// Algo errado com as conexões.
throw re;
}
finally {
if (conn != null) {
try {
conn.close();
}
catch (javax.resource.ResourceException re) {
}
}
}
}
Exemplo: Tratando Exceção de Acesso a Dados - Mapeamento de Erro em DataStoreHelper
O servidor de aplicativos fornece uma interface DataStoreHelper para mapear diferentes códigos de erro SQL do banco de dados para as exceções apropriadas no servidor de aplicativos.
Mapeamento de erro você deve porque vários fornecedores de banco de dados podem oferecer diferentes erros e códigos SQL que representam o mesmo problema. Por exemplo, a exceção de conexão stale possui códigos diferentes em diferentes bancos de dados. Os SQLCODEs do DB2 de 1015, 1034, 1036 e outros indicam que a conexão não está mais disponível devido a um problema temporário no banco de dados. O Oracle SQLCODEs de 28, 3113, 3114, e assim por diante, indicam a mesma situação.
O mapeamento destes códigos de erro para exceções padrão fornece a consistência que torna aplicativos portáveis entre diferentes instalações do servidor de aplicativos. O segmento de código a seguir ilustra como incluir dois códigos de erro no mapa de erros: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);
...
}
}
Uma opção de configuração conhecida como o Modelo de Detecção de Erros controla como o mapa de erro é usado. Na versão 6 e anterior, o Mapeamento de Exceção era a única opção disponível para o Modelo de Detecção de Erro. Na versão 7 e posterior, outra opção chamada Verificação de Exceção também está disponível. No modelo de Mapeamento de Exceção, o servidor de aplicativos consulta o mapa de erros e substitui as exceções pelo tipo de exceção correspondente listado no mapa de erros. No modelo de Verificação de Exceção, o servidor de aplicativos ainda consulta o mapa de erros com suas próprias finalidades, mas não substitui as exceções. Se desejar continuar usando o Mapeamento de Exceção, nada precisará ser alterado. O Mapeamento de Exceção é o Modelo de Detecção de Erro padrão. Se desejar usar o Modelo de Verificação de Exceções, consulte o tópico "Alterando o Modelo de Detecção de Erros par usar o Modelo de Verificação de Exceções" nos links relacionados.
Conflitos entre Chaves Estrangeiras e Impasses do Banco de Dados
A repetição de algumas mensagens de erro SQL indica problemas, como violações de integridade referencial do banco de dados, que você pode evitar usando o recurso de agrupamento de sequência de persistência gerenciada por contêiner (CMP).
Exceções Resultantes de Conflitos de Chave Estrangeira devido a Violações da Integridade Referencial do Banco de DadosUma política de RI (Referential Integrity) de banco de dados prescreve regras de como os dados são gravados e excluídos das tabelas do banco de dados para manter consistência relacional. Os requisitos de tempo de execução para o gerenciamento da persistência de beans, no entanto, pode fazer com que um aplicativo Enterprise JavaBeans (EJB) viole as regras de RI, o que pode causar exceções de banco de dados.
O valor inserir ou atualizar da FOREIGN KEY table1.name_of_foreign_key_constraint
não é igual a qualquer valor da chave pai da tabela-pai.
ouUma linha pai não pode ser excluída porque o relacionamento table1.name_of_foreign_key_constraint
não é igual a qualquer valor da chave pai da tabela-pai.
Para impedir essas exceções, você deve designar a ordem com a qual os beans de entidade atualizam as tabelas de banco de dados relacional ao definir grupos de sequência para os beans.
Exceções Resultantes de Conflito Causado por Esquemas de Optimistic Concurrency ControlAlém disso, o agrupamento de sequência pode minimizar as exceções de retrocesso da transação dos beans de entidade que são configurados para Optimistic Concurrency Control. O Optimistic Concurrency Control define que os travamentos de banco de dados sejam mantidos por uma quantidade mínima de tempo, para que o máximo de transações tenha acesso de forma consistente aos dados. Nesses banco de dados altamente disponível, transações simultâneas podem tentar travar a mesma linha de tabela e criar um conflito. As exceções resultantes podem gerar mensagens semelhantes às seguintes (produzidas em um ambiente que execute o DB2):
Execução mal sucedida causada pro conflito ou tempo limite.
Utilize o recurso de agrupamento de sequência para ordenar a persistência do bean para que um conflito de banco de dados seja menos provável.