Como usar o espelhamento de banco de dados (JDBC)

Baixar driver JDBC

O espelhamento de banco de dados é uma solução de software destinada principalmente a aumentar a disponibilidade do banco de dados e a redundância dos dados. O Microsoft JDBC Driver para SQL Server fornece suporte implícito ao espelhamento de banco de dados, de modo que, depois que ele é configurado para o banco de dados, o desenvolvedor não precisa escrever nenhum código nem executar nenhuma outra ação.

O espelhamento de banco de dados, que é implementado para cada banco de dados, mantém uma cópia de um banco de dados de produção do SQL Server em um servidor em espera. Esse servidor é um servidor em espera ativa ou passiva, dependendo da configuração e do estado da sessão de espelhamento de banco de dados. Um servidor em espera ativa oferece suporte rápido para failover sem perda de transações confirmadas. Um servidor em espera passiva oferece suporte a serviços forçados (com possível perda de dados).

O banco de dados de produção é chamado de banco de dados principal, e a cópia em espera é chamada de banco de dados espelho. O banco de dados principal e o banco de dados espelho devem estar em instâncias separadas do SQL Server (instâncias do servidor). Eles devem estar alocados em computadores separados, se possível.

A instância do servidor de produção (o servidor principal) se comunica com a instância do servidor em espera (o servidor espelho). Os servidores principal e espelho atuam como parceiros em uma sessão de espelhamento de banco de dados. Se o servidor principal falhar, o servidor espelho poderá converter seu banco de dados como o principal por meio de um processo chamado failover. Por exemplo, Parceiro_A e Parceiro_B são dois servidores parceiros, com o banco de dados principal inicialmente no Parceiro_A como servidor principal e o banco de dados espelho residindo no Parceiro_B como o servidor espelho. Se o Parceiro_A ficar offline, o banco de dados no Parceiro_B pode fazer failover para se tornar o banco de dados principal atual. Quando o Parceiro_A ingressar novamente na sessão de espelhamento, ele se tornará o servidor espelho e seu banco de dados se tornará o banco de dados espelho.

Se o servidor do Parceiro_A estiver irreparavelmente danificado, um servidor do Parceiro_C poderá ser colocado online para atuar como servidor espelho para o Parceiro_B, que agora é o servidor principal. Porém, nesse cenário, o aplicativo cliente deverá incluir lógica de programação para assegurar que as propriedades de cadeia de conexão sejam atualizadas com os novos nomes de servidor usados na configuração de espelhamento de banco de dados. Caso contrário, poderá ocorrer falha na conexão com os servidores.

Configurações alternativas de espelhamento de banco de dados oferecem diferentes níveis de desempenho e segurança de dados, e dão suporte a diversas formas de failover. Para obter mais informações, veja "Visão geral do espelhamento de banco de dados" nos Manuais Online do SQL Server.

Considerações sobre programação

Quando o servidor do banco de dados principal falhar, o aplicativo cliente receberá erros em resposta a chamadas API, o que indica que a conexão com o banco de dados foi interrompida. Quando esses erros acontecem, todas as alterações não confirmadas feitas no banco de dados são perdidas e a transação atual é revertida. Nesse cenário, o aplicativo deve fechar a conexão (ou liberar o objeto de fonte de dados) e tentar reabri-la. Ao ser estabelecida, a nova conexão é redirecionada, de forma transparente, ao banco de dados espelho, que agora age como o servidor principal, sem que o cliente precise modificar a cadeia de conexão ou o objeto de fonte de dados.

Quando uma conexão é estabelecida inicialmente, o servidor principal envia a identidade de seu parceiro de failover ao cliente que será usado quando ocorrer um failover. Quando um aplicativo tenta estabelecer uma conexão inicial com um servidor principal falho, o cliente não sabe a identidade do parceiro de failover. Para que os clientes tenham a oportunidade de lidar com esse cenário, a propriedade de cadeia de conexão failoverPartner e, opcionalmente, o método de fonte de dados setFailoverPartner permitem ao cliente especificar a identidade do parceiro de failover por sua própria conta. A propriedade do cliente é usada apenas nesse cenário; se o servidor principal estiver disponível, ela não será usada.

Observação

Quando uma propriedade failoverPartner é especificada na cadeia de conexão ou com um objeto de fonte de dados, a propriedade databaseName também deve ser definida; caso contrário, uma exceção será lançada. Se as propriedades failoverPartner e databaseName não forem especificadas explicitamente, o aplicativo não tentará fazer failover quando ocorrer falha no servidor de banco de dados principal. Em outras palavras, o redirecionamento transparente só funcionará para conexões que especifiquem explicitamente failoverPartner e databaseName. Para obter mais informações sobre failoverPartner e outras propriedades de cadeia de conexão, confira Configuração das propriedades de conexão.

Se o servidor do parceiro de failover fornecido pelo cliente não se referir a um servidor que funciona como um parceiro de failover para o banco de dados especificado, e se o servidor/banco de dados referenciado estiver em uma disposição de espelhamento, a conexão será recusada pelo servidor. Embora a classe SQLServerDataSource forneça o método getFailoverPartner, esse método só retorna o nome do parceiro de failover especificado na cadeia de conexão ou no método setFailoverPartner. Para recuperar o nome do parceiro de failover real que está sendo usado no momento, use a seguinte instrução Transact-SQL:

SELECT m.mirroring_role_DESC, m.mirroring_state_DESC,
m.mirroring_partner_instance FROM sys.databases as db,
sys.database_mirroring AS m WHERE db.name = 'MirroringDBName'
AND db.database_id = m.database_id

Observação

Você precisará alterar essa instrução para usar o nome do seu banco de dados de espelhamento.

Considere o armazenamento em cache das informações do parceiro para atualizar a cadeia de conexão ou crie uma estratégia de repetição em caso de falha na primeira tentativa de estabelecer uma conexão.

Exemplo

No exemplo a seguir, primeiro é feita uma tentativa de conectar ao servidor principal. Se isso falhar e uma exceção for lançada, será feita uma tentativa de conectar ao servidor espelho, que pode ter sido elevado a novo servidor principal. Observe o uso da propriedade failoverPartner na cadeia de conexão.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class ClientFailover {
    public static void main(String[] args) {

        String connectionUrl = "jdbc:sqlserver://serverA:1433;"
                + "encrypt=true;databaseName=AdventureWorks;integratedSecurity=true;"
                + "failoverPartner=serverB";

        // Establish the connection to the principal server.
        try (Connection con = DriverManager.getConnection(connectionUrl);
                Statement stmt = con.createStatement();) {
            System.out.println("Connected to the principal server.");

            // Note that if a failover of serverA occurs here, then an
            // exception will be thrown and the failover partner will
            // be used in the first catch block below.

            // Execute a SQL statement that inserts some data.

            // Note that the following statement assumes that the
            // TestTable table has been created in the AdventureWorks
            // sample database.
            stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
        }
        catch (SQLException se) {
            System.out.println("Connection to principal server failed, " + "trying the mirror server.");
            // The connection to the principal server failed,
            // try the mirror server which may now be the new
            // principal server.
            try (Connection con = DriverManager.getConnection(connectionUrl);
                    Statement stmt = con.createStatement();) {
                System.out.println("Connected to the new principal server.");
                stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
            }
            // Handle any errors that may have occurred.
            catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Confira também

Conectando ao SQL Server com o JDBC Driver