Resiliência de conexão (JDBC)

Baixar driver JDBC

A resiliência da ligação permite ao driver JDBC restaurar de forma transparente uma ligação inativa avariada e tentar novamente a ligação inicial se esta falhar. Este artigo aborda as duas propriedades da cadeia de ligação que controlam este comportamento (connectRetryCount e connectRetryInterval) e as definições de keepalive que o driver utiliza para detetar uma ligação de repouso interrompida. A resiliência de ligação está disponível a partir do Microsoft JDBC Driver 10.2.0 para SQL Server. Reconectar uma ligação idle avariada requer o SQL Server 2014 e versões posteriores, ou Base de Dados SQL do Azure.

Tip

A resiliência da ligação apenas tenta novamente a ligação inicial e restaura silenciosamente as ligações inativas quebradas. Para repetir automaticamente instruções com falha (por exemplo, deadlock victim 1205 ou lock timeout 1222), ou para alargar a lista de novas tentativas de ligação com números de erro personalizados (por exemplo, erros transitórios do SQL do Azure, tais como 40197 ou 40613), utilize lógica de repetição configurável. O CRL baseia-se em regras, escolhem-se os erros e o backoff, e funciona em conjunto com as funcionalidades descritas neste artigo.

Como o controlador JDBC faz novas tentativas

O controlador JDBC dispõe de três mecanismos de retentativa independentes. Funcionam em conjunto, por isso pode usar todos ao mesmo tempo:

Mecanismo O que faz Onde aprender mais
Resiliência da conexão inativa Restaura de forma transparente uma ligação ociosa quebrada (por exemplo, uma ligação em pool fechada pelo servidor ou por um balanceador de carga). Detetar ligações inativas interrompidas (este artigo)
Retentativa inicial de ligação Repete uma conexão inicial falhada de acordo com um intervalo fixo para uma lista predefinida de erros transitórios. Tentar novamente as ligações iniciais (este artigo)
Lógica de repetição configurável (CRL) Nova tentativa baseada em regras para instruções com falha e para números de erro personalizados. Introduzido no Microsoft JDBC Driver 12.10. Lógica de repetição de tentativas configurável

Tentar novamente as conexões iniciais

O driver JDBC inclui duas propriedades de ligação que controlam com que frequência e quanto tempo o driver espera antes de tentar novamente a ligação inicial. Adicione estas propriedades à cadeia de ligação ou defina-as através das propriedades da fonte de dados.

Keyword Valores Default Description
connectRetryCount Inteiro entre 0 e 255 (inclusive) 1 O número máximo de tentativas de estabelecer ou restabelecer uma conexão antes de desistir. Por predefinição, o controlador efetua uma única nova tentativa. Um valor de 0 desativa a nova tentativa.
connectRetryInterval Inteiro entre 1 e 60 (inclusive) 10 O tempo, em segundos, entre as tentativas de repetição da conexão. O condutor tenta reconectar imediatamente quando detetar uma ligação de repouso avariada, depois espera connectRetryInterval segundos antes de tentar novamente. Esta propriedade é ignorada quando connectRetryCount é 0.

O condutor executa imediatamente a primeira tentativa e espera connectRetryInterval segundos antes de cada uma seguinte, por isso connectRetryCount as tentativas duram cerca (connectRetryCount - 1) * connectRetryInterval de segundos. loginTimeout delimita toda a sequência: o controlador deixa de tentar novamente assim que o tempo decorrido mais connectRetryInterval atinge loginTimeout, o que acontece um intervalo antes de loginTimeout propriamente dito.

Estas propriedades repetem apenas a lista integrada de erros transitórios de ligação. Para a lista completa de erros abordados (4060, 40197, 40501, 40613, 49918-49920, entre outros), veja Lista de erros de ligação transitória incorporada. Para adicionar números de erro personalizados a este conjunto, ou substituí-lo completamente, use retryConn em Lógica de repetição configurável. Para tentar novamente afirmações falhadas, use retryExec no mesmo artigo.

Atenção

Se definires retryConn sem um início +, substitui a lista incorporada em vez de a estender. Qualquer erro incorporado que não menciones tu próprio, incluindo o 40613, já não é retentado.

Defina as propriedades

Definir connectRetryCount e connectRetryInterval no URL JDBC, num Properties objeto, ou num SQLServerDataSource.

No URL do JDBC:

jdbc:sqlserver://server;databaseName=db;connectRetryCount=3;connectRetryInterval=10

Com um objeto Properties. Os excertos em Java neste artigo omitem importações e wrappers de classe para maior brevidade.

Properties props = new Properties();
props.setProperty("user", "...");
props.setProperty("password", "...");
props.setProperty("connectRetryCount", "3");
props.setProperty("connectRetryInterval", "10");
Connection c = DriverManager.getConnection("jdbc:sqlserver://server;databaseName=db", props);

Com SQLServerDataSource:

SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("server");
ds.setDatabaseName("db");
ds.setUser("...");
ds.setPassword("...");
ds.setConnectRetryCount(3);
ds.setConnectRetryInterval(10);

Liga-te a uma base de dados sem servidor colocada automaticamente em pausa

Quando usa o Base de Dados SQL do Azure serverless com a autopausa ativada, a base de dados retoma à primeira tentativa de ligação. Esta tentativa falha com o erro 40613 enquanto a operação de retoma é executada. As bases de dados geralmente retomam em menos de um minuto. Para mais informações, veja Pausa automática e retomada automática.

O erro 40613 está na lista de erros de ligação transitória incorporada, por isso o driver tenta novamente a ligação. A tua aplicação não precisa do seu próprio ciclo de retentativas neste caso. As definições predefinidas não contemplam uma retoma: connectRetryCount é 1, e o controlador executa imediatamente essa única nova tentativa. Ambas as tentativas acontecem enquanto a base de dados ainda está a ser retomada, por isso a aplicação vê o erro.

Para gerir um currículo, defina as três propriedades em conjunto:

Property Por que é importante
connectRetryCount Define o número de novas tentativas. Defina-o acima do valor padrão de 1.
connectRetryInterval Espaça as novas tentativas. A primeira tentativa é imediata; o controlador aguarda este intervalo antes de cada tentativa posterior.
loginTimeout Limita toda a sequência. O condutor para de tentar novamente assim que o tempo decorrido plus connectRetryInterval atinge loginTimeout.

Os valores seguintes continuam a repetir a tentativa durante cerca de um minuto, o que abrange uma retoma típica:

jdbc:sqlserver://<server>.database.windows.net;databaseName=<database>;encrypt=true;loginTimeout=120;connectRetryCount=5;connectRetryInterval=15

Aumentar loginTimeout por si só não ajuda, porque a tentativa de conexão falha rapidamente com 40613 em vez de ficar suspensa. Levantar connectRetryCount sozinho também não ajuda, porque loginTimeout interrompe a sequência.

Detetar ligações inativas interrompidas

Uma ligação típica inativa é aquela que está num pool de ligações. O controlador considera uma ligação inativa após cerca de 30 segundos sem atividade. O servidor ou um dispositivo de rede entre o cliente e o servidor pode fechar ligações inativas, por isso o driver precisa de uma forma de perceber que o socket está morto antes da próxima consulta ser executada.

Para detetar conexões ociosas quebradas, o driver depende de pacotes keepalive TCP no nível do soquete. No Linux com Java 11 e versões posteriores, o driver ativa automaticamente os pacotes keepalive com um intervalo de 30 segundos (KeepAliveTime), com um atraso de 1 segundo entre tentativas quando ocorre uma falha (KeepAliveInterval).

Importante

No Windows e no Java 11, ou em versões anteriores, tem de configurar manualmente os mecanismos de keepalive no sistema operativo para beneficiar da recuperação de ligações inativas interrompidas. Para obter informações sobre como configurar keepalives, consulte Conexão com o banco de dados SQL do Azure.

Limitações

O condutor não pode restaurar uma ligação de repouso avariada quando alguma das seguintes condições é verdadeira:

  • Há um conjunto de resultados aberto que não está completamente analisado ou bufferizado.
  • A ligação alternava entre bases de dados e SQL do Azure.
  • Há uma transação em aberto.