Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La creación de reflejo de bases de datos es principalmente una solución de software para aumentar la disponibilidad de la base de datos y la redundancia de los datos. Microsoft JDBC Driver para SQL Server admite de forma implícita la creación de reflejo de la base de datos, por lo que el desarrollador no necesita escribir código ni realizar ninguna otra acción cuando esta se ha configurado para la base de datos.
La creación de reflejo de la base de datos, implementada para cada base de datos, conserva una copia de una base de datos de producción de SQL Server en un servidor en espera. Este servidor es un servidor en espera activa o semiactiva, según la configuración y el estado de la sesión de creación de reflejo de la base de datos. Un servidor en espera activa permite una conmutación por error rápida sin pérdida de transacciones confirmadas. Un servidor en espera activa admite forzar el servicio (con posible pérdida de datos).
La base de datos de producción se denomina base de datos principal y la copia en espera se denomina base de datos reflejada. La base de datos principal y la base de datos reflejada deben residir en instancias independientes de SQL Server (instancias del servidor) Deberían estar en equipos distintos, si es posible.
La instancia del servidor de producción (el servidor principal) se comunica con la instancia del servidor en espera (el servidor reflejado). Los servidores principal y reflejo actúan como asociados en una sesión de creación de reflejo de la base de datos. Si el servidor principal falla, el servidor espejo puede hacer que su base de datos pase a ser la base de datos principal mediante un proceso llamado conmutación por error. Por ejemplo, Partner_A y Partner_B son dos servidores asociados, con la base de datos principal inicialmente en Partner_A como servidor principal y la base de datos reflejada en Partner_B como servidor reflejado. Si Partner_A queda fuera de servicio, la base de datos de Partner_B puede pasar a ser la base de datos principal activa. Cuando Partner_A se vuelve a unir a la sesión de creación de reflejo, se convierte en el servidor reflejado y su base de datos pasa a ser la base de datos reflejada.
Si el servidor Partner_A se dañe de forma irreparable, se puede poner en línea un servidor Partner_C para que actúe como un servidor reflejado para Partner_B, que es ahora el servidor principal. No obstante, en este escenario, la aplicación cliente debe incluir una lógica de programación para asegurarse de que las propiedades de la cadena de conexión se actualizan con los nombres de servidor nuevos usados en la configuración de la creación de reflejo de la base de datos. En caso contrario, es posible que la conexión con los servidores no se realice.
Las configuraciones alternativas de reflejo de la base de datos proporcionan diferentes niveles de rendimiento y seguridad de los datos, y admiten distintas formas de conmutación por error. Para obtener más información, consulte "Información general sobre la creación de reflejo de bases de datos" en SQL Server Books Online.
Consideraciones de programación
Cuando el servidor principal genera un error, la aplicación cliente recibe mensajes de error como respuesta a las llamadas a la API que indican que se ha perdido la conexión a la base de datos. En este caso, se pierden todos los cambios sin confirmar introducidos en la base de datos y se revierte la transacción actual. En este escenario, la aplicación debe cerrar la conexión (o liberar el objeto de origen de datos) e intentar volver a abrirla. Una vez establecida la conexión, la nueva conexión se redirige de forma transparente a la base de datos reflejada, la cual actúa ahora como el servidor principal sin que el cliente tenga que modificar la cadena de conexión o el objeto de origen de datos.
Cuando se establece inicialmente una conexión, el servidor principal envía al cliente la identidad de su servidor asociado de conmutación por error, que se utilizará cuando se produzca la conmutación por error. Cuando una aplicación intenta establecer una conexión inicial con un servidor principal que ha fallado, el cliente desconoce la identidad del servidor asociado de conmutación por error. Para que los clientes puedan hacer frente a este escenario, la propiedad failoverPartner de la cadena de conexión y, opcionalmente, el método del origen de datos setFailoverPartner permiten al cliente especificar por su cuenta la identidad del servidor asociado de conmutación por error. La propiedad del cliente se usa solo en este escenario; si el servidor principal está disponible, no se usa.
Nota
Cuando se especifica failoverPartner, ya sea en la cadena de conexión o mediante un objeto de fuente de datos, la propiedad databaseName también debe establecerse; de lo contrario, se lanzará una excepción. Si failoverPartner y databaseName no se especifican explícitamente, la aplicación no intentará la conmutación por error cuando se produzcan errores en el servidor de base de datos principal. En otras palabras, la redirección transparente solo funciona para las conexiones que especifican explícitamente failoverPartner y databaseName. Para obtener más información acerca de failoverPartner y de otras propiedades de la cadena de conexión, consulte Establecimiento de las propiedades de conexión.
Si el servidor asociado para conmutación por error proporcionado por el cliente no corresponde a un servidor que actúe como asociado para conmutación por error de la base de datos especificada, y si el servidor o la base de datos mencionados forman parte de una configuración de creación de reflejo de la base de datos, el servidor rechaza la conexión. Aunque la clase SQLServerDataSource proporciona el método getFailoverPartner, este método solo devuelve el nombre del asociado de conmutación por error especificado en la cadena de conexión o el método setFailoverPartner. Para recuperar el nombre del asociado de conmutación por error usado actualmente, use la siguiente instrucción 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
Tendrá que cambiar esta sentencia para usar el nombre de la base de datos reflejo.
Plantéese la posibilidad de almacenar en caché la información del asociado para actualizar la cadena de conexión o crear una estrategia de reintento en caso de que el primer intento de conexión no se realice correctamente.
Ejemplo
En el siguiente ejemplo, se realiza un primer intento de conexión con el servidor principal. Si eso falla y se produce una excepción, se intenta establecer una conexión con el servidor espejo, que puede haber sido promovido a nuevo servidor principal. Observe el uso de la propiedad failoverPartner en la cadena de conexión.
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();
}
}
}
}