@@ -300,7 +300,6 @@ internal SessionData CurrentSessionData
300300 // FOR CONNECTION RESET MANAGEMENT
301301 private bool _fResetConnection ;
302302 private string _originalDatabase ;
303- private string _currentFailoverPartner ; // only set by ENV change from server
304303 private string _originalLanguage ;
305304 private string _currentLanguage ;
306305 private int _currentPacketSize ;
@@ -667,13 +666,7 @@ internal TdsParser Parser
667666 }
668667 }
669668
670- internal string ServerProvidedFailOverPartner
671- {
672- get
673- {
674- return _currentFailoverPartner ;
675- }
676- }
669+ internal string ServerProvidedFailoverPartner { get ; private set ; }
677670
678671 internal SqlConnectionPoolGroupProviderInfo PoolGroupProviderInfo
679672 {
@@ -1533,7 +1526,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
15331526 ! connectionOptions . MultiSubnetFailover , // ignore timeout for SniOpen call unless MSF
15341527 connectionOptions . MultiSubnetFailover ? intervalTimer : timeout ) ;
15351528
1536- if ( connectionOptions . MultiSubnetFailover && null != ServerProvidedFailOverPartner )
1529+ if ( connectionOptions . MultiSubnetFailover && ServerProvidedFailoverPartner != null )
15371530 {
15381531 // connection succeeded: trigger exception if server sends failover partner and MultiSubnetFailover is used
15391532 throw SQL . MultiSubnetFailoverWithFailoverPartner ( serverProvidedFailoverPartner : true , internalConnection : this ) ;
@@ -1561,7 +1554,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
15611554 _currentPacketSize = ConnectionOptions . PacketSize ;
15621555 _currentLanguage = _originalLanguage = ConnectionOptions . CurrentLanguage ;
15631556 CurrentDatabase = _originalDatabase = ConnectionOptions . InitialCatalog ;
1564- _currentFailoverPartner = null ;
1557+ ServerProvidedFailoverPartner = null ;
15651558 _instanceName = string . Empty ;
15661559
15671560 routingAttempts ++ ;
@@ -1599,7 +1592,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
15991592 // We only get here when we failed to connect, but are going to re-try
16001593
16011594 // Switch to failover logic if the server provided a partner
1602- if ( null != ServerProvidedFailOverPartner )
1595+ if ( ServerProvidedFailoverPartner != null )
16031596 {
16041597 if ( connectionOptions . MultiSubnetFailover )
16051598 {
@@ -1615,7 +1608,7 @@ private void LoginNoFailover(ServerInfo serverInfo,
16151608 LoginWithFailover (
16161609 true , // start by using failover partner, since we already failed to connect to the primary
16171610 serverInfo ,
1618- ServerProvidedFailOverPartner ,
1611+ ServerProvidedFailoverPartner ,
16191612 newPassword ,
16201613 newSecurePassword ,
16211614 redirectedUserInstance ,
@@ -1637,8 +1630,13 @@ private void LoginNoFailover(ServerInfo serverInfo,
16371630 {
16381631 // We must wait for CompleteLogin to finish for to have the
16391632 // env change from the server to know its designated failover
1640- // partner; save this information in _currentFailoverPartner.
1641- PoolGroupProviderInfo . FailoverCheck ( false , connectionOptions , ServerProvidedFailOverPartner ) ;
1633+ // partner; save this information in ServerProvidedFailoverPartner.
1634+
1635+ // When ignoring server provided failover partner, we must pass in the original failover partner from the connection string.
1636+ // Otherwise the pool group's failover partner designation will be updated to point to the server provided value.
1637+ string actualFailoverPartner = LocalAppContextSwitches . IgnoreServerProvidedFailoverPartner ? string . Empty : ServerProvidedFailoverPartner ;
1638+
1639+ PoolGroupProviderInfo . FailoverCheck ( false , connectionOptions , actualFailoverPartner ) ;
16421640 }
16431641 CurrentDataSource = originalServerInfo . UserServerName ;
16441642 }
@@ -1699,7 +1697,7 @@ TimeoutTimer timeout
16991697 ServerInfo failoverServerInfo = new ServerInfo ( connectionOptions , failoverHost , connectionOptions . FailoverPartnerSPN ) ;
17001698
17011699 ResolveExtendedServerName ( primaryServerInfo , ! redirectedUserInstance , connectionOptions ) ;
1702- if ( null == ServerProvidedFailOverPartner )
1700+ if ( ServerProvidedFailoverPartner == null )
17031701 {
17041702 ResolveExtendedServerName ( failoverServerInfo , ! redirectedUserInstance && failoverHost != primaryServerInfo . UserServerName , connectionOptions ) ;
17051703 }
@@ -1747,12 +1745,21 @@ TimeoutTimer timeout
17471745 ServerInfo currentServerInfo ;
17481746 if ( useFailoverHost )
17491747 {
1750- // Primary server may give us a different failover partner than the connection string indicates. Update it
1751- if ( null != ServerProvidedFailOverPartner && failoverServerInfo . ResolvedServerName != ServerProvidedFailOverPartner )
1748+ // Primary server may give us a different failover partner than the connection string indicates.
1749+ // Update it only if we are respecting server-provided failover partner values.
1750+ if ( ServerProvidedFailoverPartner != null && failoverServerInfo . ResolvedServerName != ServerProvidedFailoverPartner )
17521751 {
1753- SqlClientEventSource . Log . TryAdvancedTraceEvent ( "<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, new failover partner={1}" , ObjectID , ServerProvidedFailOverPartner ) ;
1754- failoverServerInfo . SetDerivedNames ( string . Empty , ServerProvidedFailOverPartner ) ;
1752+ if ( LocalAppContextSwitches . IgnoreServerProvidedFailoverPartner )
1753+ {
1754+ SqlClientEventSource . Log . TryTraceEvent ( "<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, Ignoring server provided failover partner '{1}' due to IgnoreServerProvidedFailoverPartner AppContext switch." , ObjectID , ServerProvidedFailoverPartner ) ;
1755+ }
1756+ else
1757+ {
1758+ SqlClientEventSource . Log . TryAdvancedTraceEvent ( "<sc.SqlInternalConnectionTds.LoginWithFailover|ADV> {0}, new failover partner={1}" , ObjectID , ServerProvidedFailoverPartner ) ;
1759+ failoverServerInfo . SetDerivedNames ( string . Empty , ServerProvidedFailoverPartner ) ;
1760+ }
17551761 }
1762+
17561763 currentServerInfo = failoverServerInfo ;
17571764 _timeoutErrorInternal . SetInternalSourceType ( SqlConnectionInternalSourceType . Failover ) ;
17581765 }
@@ -1834,7 +1841,7 @@ TimeoutTimer timeout
18341841 _activeDirectoryAuthTimeoutRetryHelper . State = ActiveDirectoryAuthenticationTimeoutRetryState . HasLoggedIn ;
18351842
18361843 // if connected to failover host, but said host doesn't have DbMirroring set up, throw an error
1837- if ( useFailoverHost && null == ServerProvidedFailOverPartner )
1844+ if ( useFailoverHost && ServerProvidedFailoverPartner == null )
18381845 {
18391846 throw SQL . InvalidPartnerConfiguration ( failoverHost , CurrentDatabase ) ;
18401847 }
@@ -1843,8 +1850,13 @@ TimeoutTimer timeout
18431850 {
18441851 // We must wait for CompleteLogin to finish for to have the
18451852 // env change from the server to know its designated failover
1846- // partner; save this information in _currentFailoverPartner.
1847- PoolGroupProviderInfo . FailoverCheck ( useFailoverHost , connectionOptions , ServerProvidedFailOverPartner ) ;
1853+ // partner.
1854+
1855+ // When ignoring server provided failover partner, we must pass in the original failover partner from the connection string.
1856+ // Otherwise the pool group's failover partner designation will be updated to point to the server provided value.
1857+ string actualFailoverPartner = LocalAppContextSwitches . IgnoreServerProvidedFailoverPartner ? failoverHost : ServerProvidedFailoverPartner ;
1858+
1859+ PoolGroupProviderInfo . FailoverCheck ( useFailoverHost , connectionOptions , actualFailoverPartner ) ;
18481860 }
18491861 CurrentDataSource = ( useFailoverHost ? failoverHost : primaryServerInfo . UserServerName ) ;
18501862 }
@@ -2068,7 +2080,8 @@ internal void OnEnvChange(SqlEnvChange rec)
20682080 {
20692081 throw SQL . ROR_FailoverNotSupportedServer ( this ) ;
20702082 }
2071- _currentFailoverPartner = rec . _newValue ;
2083+
2084+ ServerProvidedFailoverPartner = rec . _newValue ;
20722085 break ;
20732086
20742087 case TdsEnums . ENV_PROMOTETRANSACTION :
0 commit comments