Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -3431,7 +3431,7 @@ private void CheckNotificationStateAndAutoEnlist()
}

Notification.Options = SqlDependency.GetDefaultComposedOptions(_activeConnection.DataSource,
InternalTdsConnection.ServerProvidedFailOverPartner,
InternalTdsConnection.ServerProvidedFailoverPartner,
identityUserName, _activeConnection.Database);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,6 @@ internal SessionData CurrentSessionData
// FOR CONNECTION RESET MANAGEMENT
private bool _fResetConnection;
private string _originalDatabase;
private string _currentFailoverPartner; // only set by ENV change from server
private string _originalLanguage;
private string _currentLanguage;
private int _currentPacketSize;
Expand Down Expand Up @@ -667,13 +666,7 @@ internal TdsParser Parser
}
}

internal string ServerProvidedFailOverPartner
{
get
{
return _currentFailoverPartner;
}
}
internal string ServerProvidedFailoverPartner { get; private set; }

internal SqlConnectionPoolGroupProviderInfo PoolGroupProviderInfo
{
Expand Down Expand Up @@ -1533,7 +1526,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
!connectionOptions.MultiSubnetFailover, // ignore timeout for SniOpen call unless MSF
connectionOptions.MultiSubnetFailover ? intervalTimer : timeout);

if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner)
if (connectionOptions.MultiSubnetFailover && ServerProvidedFailoverPartner != null)
{
// connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used
throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: true, internalConnection: this);
Expand Down Expand Up @@ -1561,7 +1554,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
_currentPacketSize = ConnectionOptions.PacketSize;
_currentLanguage = _originalLanguage = ConnectionOptions.CurrentLanguage;
CurrentDatabase = _originalDatabase = ConnectionOptions.InitialCatalog;
_currentFailoverPartner = null;
ServerProvidedFailoverPartner = null;
_instanceName = string.Empty;

routingAttempts++;
Expand Down Expand Up @@ -1599,7 +1592,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
// We only get here when we failed to connect, but are going to re-try

// Switch to failover logic if the server provided a partner
if (null != ServerProvidedFailOverPartner)
if (ServerProvidedFailoverPartner != null)
{
if (connectionOptions.MultiSubnetFailover)
{
Expand All @@ -1615,7 +1608,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
LoginWithFailover(
true, // start by using failover partner, since we already failed to connect to the primary
serverInfo,
ServerProvidedFailOverPartner,
ServerProvidedFailoverPartner,
newPassword,
newSecurePassword,
redirectedUserInstance,
Expand All @@ -1637,8 +1630,13 @@ private void LoginNoFailover(ServerInfo serverInfo,
{
// We must wait for CompleteLogin to finish for to have the
// env change from the server to know its designated failover
// partner; save this information in _currentFailoverPartner.
PoolGroupProviderInfo.FailoverCheck(false, connectionOptions, ServerProvidedFailOverPartner);
// partner; save this information in ServerProvidedFailoverPartner.

// When ignoring server provided failover partner, we must pass in the original failover partner from the connection string.
// Otherwise the pool group's failover partner designation will be updated to point to the server provided value.
string actualFailoverPartner = LocalAppContextSwitches.IgnoreServerProvidedFailoverPartner ? "" : ServerProvidedFailoverPartner;

PoolGroupProviderInfo.FailoverCheck(false, connectionOptions, actualFailoverPartner);
}
CurrentDataSource = originalServerInfo.UserServerName;
}
Expand Down Expand Up @@ -1699,7 +1697,7 @@ TimeoutTimer timeout
ServerInfo failoverServerInfo = new ServerInfo(connectionOptions, failoverHost, connectionOptions.FailoverPartnerSPN);

ResolveExtendedServerName(primaryServerInfo, !redirectedUserInstance, connectionOptions);
if (null == ServerProvidedFailOverPartner)
if (ServerProvidedFailoverPartner == null)
{
ResolveExtendedServerName(failoverServerInfo, !redirectedUserInstance && failoverHost != primaryServerInfo.UserServerName, connectionOptions);
}
Expand Down Expand Up @@ -1747,12 +1745,21 @@ TimeoutTimer timeout
ServerInfo currentServerInfo;
if (useFailoverHost)
{
// Primary server may give us a different failover partner than the connection string indicates. Update it
if (null != ServerProvidedFailOverPartner && failoverServerInfo.ResolvedServerName != ServerProvidedFailOverPartner)
// Primary server may give us a different failover partner than the connection string indicates.
// Update it only if we are respecting server-provided failover partner values.
if (ServerProvidedFailoverPartner != null && failoverServerInfo.ResolvedServerName != ServerProvidedFailoverPartner)
{
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, new failover partner={1}", ObjectID, ServerProvidedFailOverPartner);
failoverServerInfo.SetDerivedNames(string.Empty, ServerProvidedFailOverPartner);
if (LocalAppContextSwitches.IgnoreServerProvidedFailoverPartner)
{
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, Ignoring server provided failover partner '{1}' due to IgnoreServerProvidedFailoverPartner AppContext switch.", ObjectID, ServerProvidedFailoverPartner);
}
else
{
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, new failover partner={1}", ObjectID, ServerProvidedFailoverPartner);
failoverServerInfo.SetDerivedNames(string.Empty, ServerProvidedFailoverPartner);
}
}

currentServerInfo = failoverServerInfo;
_timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.Failover);
}
Expand Down Expand Up @@ -1834,7 +1841,7 @@ TimeoutTimer timeout
_activeDirectoryAuthTimeoutRetryHelper.State = ActiveDirectoryAuthenticationTimeoutRetryState.HasLoggedIn;

// if connected to failover host, but said host doesn't have DbMirroring set up, throw an error
if (useFailoverHost && null == ServerProvidedFailOverPartner)
if (useFailoverHost && ServerProvidedFailoverPartner == null)
{
throw SQL.InvalidPartnerConfiguration(failoverHost, CurrentDatabase);
}
Expand All @@ -1843,8 +1850,13 @@ TimeoutTimer timeout
{
// We must wait for CompleteLogin to finish for to have the
// env change from the server to know its designated failover
// partner; save this information in _currentFailoverPartner.
PoolGroupProviderInfo.FailoverCheck(useFailoverHost, connectionOptions, ServerProvidedFailOverPartner);
// partner.

// When ignoring server provided failover partner, we must pass in the original failover partner from the connection string.
// Otherwise the pool group's failover partner designation will be updated to point to the server provided value.
string actualFailoverPartner = LocalAppContextSwitches.IgnoreServerProvidedFailoverPartner ? failoverHost : ServerProvidedFailoverPartner;

PoolGroupProviderInfo.FailoverCheck(useFailoverHost, connectionOptions, actualFailoverPartner);
}
CurrentDataSource = (useFailoverHost ? failoverHost : primaryServerInfo.UserServerName);
}
Expand Down Expand Up @@ -2068,7 +2080,8 @@ internal void OnEnvChange(SqlEnvChange rec)
{
throw SQL.ROR_FailoverNotSupportedServer(this);
}
_currentFailoverPartner = rec._newValue;

ServerProvidedFailoverPartner = rec._newValue;
break;

case TdsEnums.ENV_PROMOTETRANSACTION:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3814,7 +3814,7 @@ private void CheckNotificationStateAndAutoEnlist()
}

Notification.Options = SqlDependency.GetDefaultComposedOptions(_activeConnection.DataSource,
InternalTdsConnection.ServerProvidedFailOverPartner,
InternalTdsConnection.ServerProvidedFailoverPartner,
identityUserName, _activeConnection.Database);
}

Expand Down
Loading