Bien sabemos que la nueva solución de failover presentado por Microsoft en esta versión de SQL Server denominada SQL Server 2005, cuyo nombre de laboratorio fue “Yukon”, se presenta con dos tipos de mirror o espejado de bases de datos, sincrónico y asincrónico cuya disponibilidad depende de la versión de SQL Server que se encuentren corriendo, para la versión enterprise ambas características están disponibles en tanto para la versión standard solo sincrónico.
El motivo del presente, es dar un acercamiento bajo que escenarios y espacio de nombres se puede utilizar la propiedad “failover partner”, para direccionar las transacciones, ante una caída del servidor principal o bien una base de datos.
A continuación describiremos el entorno de prueba, los objetos utilizados y los casos aplicados con su correspondiente acción y resultado.
Entorno de prueba:
Windows 2003 server enterprise con service pack 2
MSSQL2K5 enterprise con service pack 2
VB.net
Framework 2.0
ADO.NET
Espacio de nombres:
Imports System.Data.SqlClient
Imports System.Data.OleDb
Objetos de base de datos:
USE [mibase]
GO
/****** Object: Table [dbo].[Tabla1] Script Date: 09/27/2006 16:15:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING OFF
GO
DROP TABLE Tabla1
GO
CREATE TABLE [dbo].[Tabla1](
[id] [smallint] NULL,
[nombre] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AI NULL,
[diahora] [datetime] NULL
) ON [PRIMARY]
SET ANSI_PADDING ON
ALTER TABLE [dbo].[Tabla1] ADD [server] [varchar](20) COLLATE SQL_Latin1_General_CP1_CI_AI NULL
GO
SET ANSI_PADDING OFF
GO
DROP PROCEDURE sp_insert
GO
CREATE PROCEDURE sp_insert AS
INSERT INTO tabla1 VALUES (1,'HOLA MUNDO',getdate(),@@servername)
INSERT INTO tabla1 VALUES (1,'PEPEPEPEPE',getdate(),@@servername)
INSERT INTO tabla1 VALUES (1,'UUUUUHAHHH',getdate(),@@servername)
INSERT INTO tabla1 VALUES (1,'HOLALALALALLSLSLSKSKS',getdate(),@@servername)
INSERT INTO tabla1 VALUES (1,'BANCO X CUENTA CORRIENTE',getdate(),@@servername)
INSERT INTO tabla1 VALUES (1,'EL LADRON DE CUERPOS ANNE RICE',getdate(),@@servername)
GO
DROP PROCEDURE sp_select
GO
CREATE PROCEDURE sp_select AS
select id,nombre,diahora,server from tabla1
GO
---------------------------------------------------------------------------------
Caso A)
Clases:
SqlConnection
SqlCommand
Código:
Public Sub conectarseNative_Insert()
Dim da As SqlConnection
Dim dt As SqlCommand
Dim sel, sCnn As String
Dim cant As Integer
On Error GoTo HayError
da = New SqlConnection
sCnn = "User ID=" & txtusuario.Text & ";Password=" & txtPass.Text & ";Data Source=" & txtserver.Text & ";Failover Partner=" & txtfailover.Text & ";initial Catalog= mibase"
sel = "exec mibase..sp_insert;"
da.ConnectionString = sCnn
da.Open()
dt = New SqlCommand(sel, da)
cant = dt.ExecuteNonQuery()
MsgBox(cant)
da.Close()
HayError:
If Err.Number <> 0 Then
MsgBox("Error:" & Err.Number & "---" & Err.Description, MsgBoxStyle.Information)
Else
MsgBox("Insert Exitoso")
End If
End Sub
Aclaración:
En cada escenario el estado ´inactivo´ se simulo desconectando el cable de red que unía a cada servidor, o bien, apagando en forma inesperada el servidor afectado o con una bajada correcta del mismo.
La prueba se realizo con una pequeña aplicación donde se ingresaban los datos y se ejecutaba un stored procedure(Como se habran dado cuenta en el código).

Acción: Se ingresa al string de conexión, el principal y el mirror y luego se ejecuta el stored procedure “sp_insert”.
Resultado: Realiza en forma satisfactoria la inserción de registros

Acción: Se ingresa el principal como mirror y viceversa, luego se ejecuta el stored procedure “sp_insert”.
Resultado: Redirecciona la ejecución del stored al verdadero servidor principal y realiza en forma satisfactoria la inserción de registros.

Acción: Se ingresa el principal y mirror, pero con el mirror caído y luego se ejecuta el stored procedure “sp_insert”.
Resultado: Realiza en forma satisfactoria la inserción de registros.

Acción: Se ingresa el principal y mirror, pero el principal esta bajo y luego se ejecuta el stored procedure “sp_insert”.
Resultado: Se produce un Error de conexión.

Acción: Se produce un failover y se cambian los roles físicamente, pero los string de conexiones siguen apuntado al estado anterior.
Resultado: Redirecciona la ejecución del stored “sp_insert” al verdadero servidor principal y realiza en forma satisfactoria la inserción de registros.

Acción: Se ingresa en el string de conexión, el principal como mirror y viceversa, pero con el servidor mirror bajo, luego se ejecuta el stored procedure “sp_insert”.
Resultado: Redirecciona la ejecución del stored al verdadero servidor principal y realiza en forma satisfactoria la inserción de registros.
Caso B)
Clases:
OleDbDataAdapter
Código:
Public Sub conectarseNative_Select()
Dim da As OleDbDataAdapter
Dim dt As DataTable
Dim n As Integer
Dim sel, sCnn As String
Dim id As Integer
Dim nombre, server, diahora As String
On Error GoTo HayError
sel = "exec mibase..sp_select;"
sCnn = "Provider=SQLNCLI.1; User ID=" & txtusuario.Text & ";Password=" & txtPass.Text & ";Data Source=" & txtserver.Text & ";Failover Partner=" & txtfailover.Text & ""
' Crear el DataAdapter
da = New OleDbDataAdapter(sel, sCnn)
' Llenar el DataTable
dt = New DataTable
da.Fill(dt)
'Comienzo a chequear contenido del data adapter
n = dt.Rows.Count
If n = 0 Then
MsgBox("No hay registros", MsgBoxStyle.Critical)
Else
'
' Asignar a las variables el contenido del registro
id = dt.Rows(0)("id").ToString
nombre = dt.Rows(0)("nombre").ToString
diahora = dt.Rows(0)("diahora").ToString
server = dt.Rows(0)("server").ToString
MsgBox(id & nombre & diahora & server, MsgBoxStyle.Information)
End If
HayError:
If Err.Number <> 0 Then
MsgBox("Error:" & Err.Number & "---" & Err.Description, MsgBoxStyle.Information)
End If
End Sub

Acción: Se produce un failover se cambian los roles físicamente pero el string de conexión, sigue apuntado al estado anterior, luego se ejecuta el stored procedure “sp_insert”.
Resultado: Cancela la ejecución por Error code 5 “Multiple step ole db operation generated errors”.

Accion: Sin failover, se ingresa el principal como mirror y viceversa, luego se ejecuta el stored procedure de “sp_select”.
Resultado: Cancela la ejecución del stored procedure sp_select por Error code 5 “Multiple step ole db operation generated errors”.
Conclusión:
De acuerdo a lo observado, las conexiones mediante la propiedad “Failover Partner” utilizando las clases sqlconnection, sqlcommand de SQLClient perteneciente al Framework 2.0 funciona correctamente.
En tanto con la clase OleDbDataAdapter de Oledb perteneciente al Framework 2.0, no es soportado.
Por lo tanto, para utilizar la propiedad “Failover partner” hay que utilizar sqlclient.
Espero que sirva y un abrazo virtual para todos,
JuanPL
Link's relacionados:
Mirror
http://www.todosql.com/blog/200705/mirror-y-log-transaccional-en-sql-ser...
http://www.todosql.com/blog/200703/cambio-de-cuentas-en-sql-server-2005
http://www.todosql.com/blog/200703/database-mirroring-login-attempt-fail...