Compartilhar via


Manipular erros transitórios e conectar-se com eficiência ao Banco de Dados do Azure para MySQL

APLICA-SE A: Banco de Dados do Azure para MySQL – Servidor Único

Importante

O servidor único do Banco de Dados do Azure para MySQL está no caminho da desativação. É altamente recomendável que você atualize para o servidor flexível do Banco de Dados do Azure para MySQL. Para obter mais informações sobre a migração para o servidor flexível do Banco de Dados do Azure para MySQL, confira O que está acontecendo com o Servidor Único do Banco de Dados do Azure para MySQL?

Este artigo descreve como tratar erros transitórios e conectar-se de modo eficiente com o Banco de Dados do Azure para MySQL.

Erros transitórios

Um erro transitório, também conhecido como uma falha transitória, é um erro que será resolvido por si só. Geralmente, esses erros manifestam como uma conexão para o servidor de banco de dados que está sendo descartado. Além disso, as novas conexões com um servidor não podem ser abertas. Os erros transitórios podem ocorrer, por exemplo, quando ocorre uma falha de hardware ou de rede. Outro motivo pode ser uma nova versão de um serviço PaaS que está sendo distribuída. A maioria desses eventos é automaticamente mitigada pelo sistema em menos de 60 segundos. Uma prática recomendada para projetar e desenvolver aplicativos na nuvem é esperar erros transitórios. Suponha que pode acontecer em qualquer componente a qualquer momento e ter a lógica apropriada em vigor para lidar com essas situações.

Tratamento de erros transitórios

Os erros transitórios devem ser manipulados usando a lógica de repetição. Situações em que devem ser consideradas:

  • Ocorre um erro quando você tentar abrir uma conexão
  • Uma conexão ociosa é descartada no lado do servidor. Quando você tenta emitir um comando, ele não pode ser executado
  • Uma conexão ativa que esteja executando um comando é descartada.

A primeira e a segunda ocorrência são razoavelmente diretas de lidar. Tente abrir a conexão novamente. Quando você tiver êxito, o erro transitório terá sido reduzido pelo sistema. Você pode usar seu Banco de Dados do Azure para MySQL novamente. Recomendamos ter esperas antes de tentar novamente a conexão. Desista se as tentativas iniciais falharem. Dessa forma, o sistema pode usar todos os recursos disponíveis para superar a situação de erro. Um bom padrão a seguir é:

  • Aguarde cinco segundos até a primeira tentativa.
  • Para cada próxima repetição, a espera aumenta exponencialmente, para até 60 segundos.
  • Defina um número máximo de repetições no ponto em que seu aplicativo considera que a operação falhou.

Quando uma conexão com uma transação ativa falha, é mais difícil de lidar com a recuperação corretamente. Há dois casos: se a transação era somente leitura por natureza, é seguro para reabrir a conexão e tentar a transação novamente. Se, no entanto, a transação também estava gravando no banco de dados, será necessário determinar se a transação foi revertida ou se ela foi bem-sucedida antes da ocorrência do erro transitório. Nesse caso, você pode simplesmente não ter recebido a confirmação do commit do servidor de banco de dados.

Uma maneira de fazer isso, é gerar uma ID exclusiva no cliente que é usado para todas as tentativas. Você pode passar essa ID exclusiva como parte da transação para o servidor e armazená-los em uma coluna com uma restrição exclusiva. Dessa forma, com segurança, você pode repetir a transação. Ela terá êxito se a transação anterior tiver sido revertida e a ID exclusiva do cliente gerada ainda não existir no sistema. Ocorrerá uma falha indicando que uma violação de chave duplicada se a ID exclusiva foi armazenada anteriormente porque a transação anterior foi concluída com êxito.

Quando o programa se comunica com o Banco de Dados do Azure para MySQL por meio de um middleware de terceiros, pergunte ao fornecedor se o middleware contém lógica de repetição para erros transitórios.

Teste a lógica de repetição. Por exemplo, tente executar seu código durante o dimensionamento os recursos de computação do seu servidor Banco de Dados do Azure para MySQL. Seu aplicativo deve lidar com o breve tempo de inatividade encontrado durante a operação sem qualquer problema.

Conectar-se de modo eficiente ao Banco de Dados do Azure para MySQL

As conexões de banco de dados são um recurso limitado, portanto, fazer uso efetivo do pool de conexões para acessar o banco de dados do Azure para MySQL otimiza o desempenho. A seção abaixo explica como usar o pool de conexões ou conexões persistentes para acessar com mais eficiência o banco de dados do Azure para MySQL.

O gerenciamento de conexões de banco de dados pode ter um impacto significativo no desempenho do aplicativo como um todo. Para otimizar o desempenho do seu aplicativo, o objetivo deve ser reduzir o número de vezes que as conexões são estabelecidas e o tempo para estabelecer conexões em caminhos de código-chave. É altamente recomendável usar o pool de conexões de banco de dados ou conexões persistentes para se conectar ao banco de dados do Azure para MySQL. O pool de conexões de banco de dados lida com a criação, o gerenciamento e a alocação de conexões de banco de dados. Quando um programa solicita uma conexão de banco de dados, ele prioriza a alocação de conexões de banco de dados ociosas existentes, em vez da criação de uma nova conexão. Depois que o programa terminar de usar a conexão de banco de dados, a conexão será recuperada na preparação para uso posterior, em vez de simplesmente ser fechada.

Para um exemplo melhor, este artigo fornece um trecho de código de exemplo que usa Java como exemplo. Para obter mais informações, veja a DBCP comum do Apache.

Observação

O servidor configura um mecanismo de tempo limite para fechar uma conexão que esteve em estado ocioso por algum tempo para liberar recursos. Certifique-se de configurar o sistema de verificação para garantir a eficácia de conexões persistentes quando estiverem em uso. Para obter mais informações, consulte Configurar sistemas de verificação no lado do cliente para garantir a eficácia de conexões persistentes.

O conceito de conexões persistentes é semelhante ao do pool de conexões. A substituição de conexões curtas com conexões persistentes exige apenas pequenas alterações no código, mas tem um grande efeito em termos de melhorar o desempenho em muitos cenários de aplicativos típicos.

Acessar bancos de dados usando o mecanismo de espera e de repetição com conexões curtas

Caso tenha limitações de recursos, é altamente recomendável usar o pool de banco de dados ou conexões persistentes para acessar bancos de dados. Se seu aplicativo usar conexões curtas e experimentar falhas de conexão ao abordar o limite superior no número de conexões simultâneas, será possível tentar o mecanismo de espera e de repetição. É possível definir um tempo de espera apropriado, com um tempo de espera mais curto após a primeira tentativa. Depois disso, é possível tentar aguardar eventos várias vezes.

Configurar mecanismos de verificação em clientes para confirmar a eficácia de conexões persistentes

O servidor configura um mecanismo de tempo limite para fechar uma conexão que esteve em estado ocioso por algum tempo para liberar recursos. Quando o cliente acessa o banco de dados novamente, é equivalente a criar uma nova solicitação de conexão entre o cliente e o servidor. Para garantir a eficácia das conexões quando são usadas, configure um mecanismo de verificação no cliente. Conforme mostrado no exemplo a seguir, é possível usar o pool de conexões do Tomcat JDBC para configurar esse mecanismo de verificação.

Ao definir o parâmetro TestOnBorrow, quando há uma nova solicitação, o pool de conexões verifica automaticamente a eficácia de todas as conexões ociosas disponíveis. Se essa conexão for eficaz, o pool de conexão retornado de outra forma retornará a conexão. O pool de conexões cria uma nova conexão efetiva e a retorna. Esse processo garante que o banco de dados seja acessado com eficiência.

Para obter informações sobre as configurações específicas, consulte o documento introdução oficial do pool de conexões JDBC. Você precisa definir principalmente os três parâmetros a seguir: TestOnBorrow (definido como true), ValidationQuery (definido como SELECT 1) e ValidationQueryTimeout (definido como 1). O código de exemplo específico pode ser visto a seguir:

public class SimpleTestOnBorrowExample {
      public static void main(String[] args) throws Exception {
          PoolProperties p = new PoolProperties();
          p.setUrl("jdbc:mysql://localhost:3306/mysql");
          p.setDriverClassName("com.mysql.jdbc.Driver");
          p.setUsername("root");
          p.setPassword("password");
            // The indication of whether objects will be validated by the idle object evictor (if any). 
            // If an object fails to validate, it will be dropped from the pool. 
            // NOTE - for a true value to have any effect, the validationQuery or validatorClassName parameter must be set to a non-null string. 
          p.setTestOnBorrow(true); 

            // The SQL query that will be used to validate connections from this pool before returning them to the caller.
            // If specified, this query does not have to return any data, it just can't throw a SQLException.
          p.setValidationQuery("SELECT 1");

            // The timeout in seconds before a connection validation queries fail. 
            // This works by calling java.sql.Statement.setQueryTimeout(seconds) on the statement that executes the validationQuery. 
            // The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts. 
            // A value less than or equal to zero will disable this feature.
          p.setValidationQueryTimeout(1);
            // set other useful pool properties.
          DataSource datasource = new DataSource();
          datasource.setPoolProperties(p);

          Connection con = null;
          try {
            con = datasource.getConnection();
            // execute your query here
          } finally {
            if (con!=null) try {con.close();}catch (Exception ignore) {}
          }
      }
  }

Próximas etapas