Utilizzo del mirroring del database (JDBC)
Il mirroring del database è principalmente una soluzione software per l'aumento della disponibilità del database e della ridondanza dei dati. Il driver JDBC per Microsoft SQL Server fornisce supporto implicito per il mirroring del database, in modo che lo sviluppatore non debba scrivere alcun codice o eseguire qualsiasi altra azione una volta configurato per il database.
Il mirroring del database, implementato per ciascun database, consente di conservare una copia di un database di produzione di SQL Server in un server di standby. Questo server è un server standby hot o warm, a seconda della configurazione e dello stato della sessione di mirroring del database. Un server standby hot supporta il failover rapido senza perdita delle transazioni approvate, mentre un server standby warm supporta la forzatura del servizio (con possibile perdita di dati).
Il database di produzione è denominato database principale, mentre la copia di standby copy viene chiamata database mirror. Il database principale e il database mirror devono risiedere in istanze separate di SQL Server (istanze del server) e, se possibile, devono risiedere in computer separati.
L'istanza del server di produzione, denominata server principale, comunica con l'istanza del server di standby, denominata server mirror. I server principale e mirror sono partner all'interno di una sessione di mirroring del database. Se si verifica un errore nel server principale, il server mirror è in grado di creare un database nel database principale tramite un processo denominato failover. Ad esempio, Partner_A e Partner_B sono due server partner, con il database principale inizialmente in Partner_A come server principale e il database mirror che risiede in Partner_B come server mirror. Se Partner_A è in offline, il database in Partner_B esegue il failover per diventare il database principale corrente. Quando Partner_A torna nella sessione di mirroring, diventa il server mirror e il suo database diventa il database mirror.
Nel caso in cui il server Partner_A è irrimediabilmente danneggiato, è possibile portare online un server Partner_C affinché funga da server mirror per Partner_B, che è ora il server principale. Tuttavia, in questo scenario l'applicazione client deve includere la logica di programmazione per assicurare che le proprietà della stringa di connessione siano aggiornate con i nuovi nomi server utilizzati nella configurazione di mirroring del database. In caso contrario, la connessione ai server non riesce.
Le configurazioni alternative di mirroring del database offrono livelli differenti di prestazioni e protezione dei dati e supportano form differenti di failover. Per ulteriori informazioni, vedere "Panoramica del mirroring del database" nella documentazione online di SQL Server.
Considerazioni sulla programmazione
Se si verifica un errore nel server database principale, l'applicazione client riceve errori in risposta alle chiamate API, che indicano che la connessione al database è stata persa. Se ciò si verifica, le modifiche al database non salvate vanno perse e si verifica il rollback della transazione. Se ciò avviene, è necessario chiudere la connessione (o rilasciare l'oggetto origine dati) e tentare di riaprirla. La nuova connessione viene reindirizzata in maniera trasparente al database mirror, che funge ora da server principale, senza che il client debba modificare la stringa di connessione o l'oggetto origine dati.
Quando viene inizialmente stabilita una connessione, il server principale invia l'identità del partner di failover al client che verrà utilizzando quando si verifica il failover. Se un'applicazione tenta di stabilire una connessione iniziale con un server principale con errori, il client non riconosce l'identità del partner di failover. Per consentire ai client di gestire questo scenario, la proprietà della stringa di connessione failoverPartner, e facoltativamente il metodo di origine dati setFailoverPartner, consentono al client di specificare autonomamente l'identità del partner di failover. La proprietà client viene utilizzata solo in questo scenario. Se il server principale è disponibile, non viene utilizzata.
Nota
Se la proprietà failoverPartner viene specificata nella stringa di connessione o nell'oggetto origine dati, è necessario impostare anche la proprietà databaseName. In caso contrario, verrà generata un'eccezione. Se le proprietà failoverPartner e databaseName non sono specificate in modo esplicito, l'applicazione non tenterà di eseguire il failover in caso di errore del server database principale. In altri termini, il reindirizzamento trasparente funziona solo per connessioni che specificano in modo esplicito le proprietà failoverPartner e databaseName. Per ulteriori informazioni su failoverPartner e su altre proprietà della stringa di connessione, vedere Impostazione delle proprietà delle connessioni.
Se il server del partner di failover fornito dal client non fa riferimento a un server che funge da partner di failover del database specificato, la connessione viene rifiutata dal server. Anche se la classe SQLServerDataSource fornisce il metodo getFailoverPartner, tale metodo restituisce solo il nome del partner di failover specificato nella stringa di connessione o il metodo setFailoverPartner. Per recuperare il nome del partner di failover effettivo utilizzato, utilizzare la seguente istruzione 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
Nota
Per utilizzare il nome del database di mirroring, è necessario modificare questa istruzione.
Si consiglia di memorizzare le informazioni sul partner per aggiornare la stringa di connessione oppure progettare una strategia di riesecuzione dei tentativi nel caso in cui si verifichi un errore nel primo tentativo di connessione.
Esempio
Nel seguente esempio, viene eseguito un primo tentativo di connessione al server principale. Se il tentativo non riesce e viene generata un'eccezione, viene eseguito un tentativo di connessione al server mirror, che potrebbe essere stato promosso a nuovo server principale. Notare l'utilizzo della proprietà failoverPartner nella stringa di connessione.
import java.sql.*;
public class clientFailover {
public static void main(String[] args) {
// Create a variable for the connection string.
String connectionUrl = "jdbc:sqlserver://serverA:1433;" +
"databaseName=AdventureWorks;integratedSecurity=true;" +
"failoverPartner=serverB";
// Declare the JDBC objects.
Connection con = null;
Statement stmt = null;
try {
// Establish the connection to the principal server.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
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.
// Create and execute an SQL statement that inserts some data.
stmt = con.createStatement();
// 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)");
}
// Handle any errors that may have occurred.
catch (SQLException se) {
try {
// The connection to the principal server failed,
// try the mirror server which may now be the new
// principal server.
System.out.println("Connection to principal server failed, " +
"trying the mirror server.");
con = DriverManager.getConnection(connectionUrl);
System.out.println("Connected to the new principal server.");
stmt = con.createStatement();
stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
}
catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
// Close the JDBC objects.
finally {
if (stmt != null) try { stmt.close(); } catch(Exception e) {}
if (con != null) try { con.close(); } catch(Exception e) {}
}
}
}