Resolver erros transitórios e ligar de forma eficiente à Base 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 de desativação. É altamente recomendável que você atualize para o Banco de Dados do Azure para o servidor flexível MySQL. Para obter mais informações sobre como migrar para o Banco de Dados do Azure para servidor flexível MySQL, consulte O que está acontecendo com o Banco de Dados do Azure para Servidor Único MySQL?

Este artigo descreve como lidar com erros transitórios e conectar-se de forma eficiente ao Banco de Dados do Azure para MySQL.

Erros transitórios

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

Tratamento de erros transitórios

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

  • Ocorre um erro quando tenta abrir uma ligaçã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 atualmente está executando um comando é descartada.

O primeiro e o segundo caso são bastante simples de manusear. Tente abrir a conexão novamente. Quando você tiver êxito, o erro transitório foi atenuado pelo sistema. Você pode usar seu Banco de Dados do Azure para MySQL novamente. Recomendamos esperar antes de tentar novamente a conexão. Recue se as novas tentativas iniciais falharem. Desta forma, o sistema pode usar todos os recursos disponíveis para superar a situação de erro. Um bom padrão a seguir é:

  • Aguarde 5 segundos antes da primeira tentativa.
  • Para cada nova tentativa seguinte, o aumento exponencial da espera, até 60 segundos.
  • Defina um número máximo de novas tentativas em que seu aplicativo considera que a operação falhou.

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

Uma maneira de fazer isso, é gerar um ID exclusivo no cliente que é usado para todas as tentativas. Você passa essa ID exclusiva como parte da transação para o servidor e a armazena em uma coluna com uma restrição exclusiva. Desta forma, você pode repetir a transação com segurança. Ele terá êxito se a transação anterior foi revertida e o ID exclusivo gerado pelo cliente ainda não existe no sistema. Ele falhará indicando uma violação de chave duplicada se o ID exclusivo foi armazenado anteriormente porque a transação anterior foi concluída com êxito.

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

Certifique-se de testar sua lógica de repetição novamente. Por exemplo, tente executar seu código enquanto dimensiona para cima ou para baixo os recursos de computação do seu Banco de Dados do Azure para o servidor MySQL. Seu aplicativo deve lidar com o breve tempo de inatividade encontrado durante esta operação sem problemas.

Conecte-se de forma 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 é recuperada em preparação para uso posterior, em vez de simplesmente ser fechada.

Para melhor ilustração, este artigo fornece uma parte do código de exemplo que usa JAVA como exemplo. Para obter mais informações, consulte Apache common DBCP.

Nota

O servidor configura um mecanismo de tempo limite para fechar uma conexão que está em estado ocioso há algum tempo para liberar recursos. Certifique-se de configurar o sistema de verificação para garantir a eficácia das conexões persistentes quando você as estiver usando. 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 de pool de conexões. A substituição de conexões curtas por conexões persistentes requer apenas pequenas alterações no código, mas tem um efeito importante em termos de melhoria do desempenho em muitos cenários típicos de aplicativos.

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

Se você tiver limitações de recursos, é altamente recomendável usar o pool de bancos de dados ou conexões persistentes para acessar bancos de dados. Se o seu aplicativo usa conexões curtas e experimenta falhas de conexão quando você se aproxima do limite superior do número de conexões simultâneas, você pode tentar esperar e repetir o mecanismo. Você pode definir um tempo de espera apropriado, com um tempo de espera menor após a primeira tentativa. Depois disso, você pode tentar esperar por 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 está em estado ocioso há 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 durante o processo de usá-las, configure um mecanismo de verificação no cliente. Conforme mostrado no exemplo a seguir, você pode usar o pool de conexões JDBC do Tomcat 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 tal conexão for efetiva, seu pool de conexões retornado diretamente, caso contrário, retirará a conexão. Em seguida, o pool de conexões cria uma nova conexão efetiva e a retorna. Esse processo garante que o banco de dados seja acessado de forma eficiente.

Para obter informações sobre as configurações específicas, consulte o documento de 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 é mostrado abaixo:

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óximos passos