in MySQL.Data/src/MySqlConnection.cs [600:720]
internal async Task OpenAsync(bool execAsync, CancellationToken cancellationToken)
{
if (State != ConnectionState.Closed)
Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen));
if (hasBeenDisposed)
Throw(new InvalidOperationException("The connection had been disposed."));
// start up our interceptors
_exceptionInterceptor = new ExceptionInterceptor(this);
commandInterceptor = new CommandInterceptor(this);
SetState(ConnectionState.Connecting, true);
AssertPermissions();
Settings.WebAuthnActionRequested = WebAuthnActionRequested;
//TODO: SUPPORT FOR 452 AND 46X
// if we are auto enlisting in a current transaction, then we will be
// treating the connection as pooled
if (Settings.AutoEnlist && Transaction.Current != null)
{
driver = DriverTransactionManager.GetDriverInTransaction(Transaction.Current);
if (driver != null && (driver.IsInActiveUse || !driver.Settings.EquivalentTo(this.Settings)))
Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported));
}
MySqlConnectionStringBuilder currentSettings = Settings;
try
{
if (!Settings.Pooling || MySqlPoolManager.Hosts == null)
{
FailoverManager.Reset();
if (Settings.DnsSrv)
{
var dnsSrvRecords = DnsSrv.GetDnsSrvRecords(Settings.Server);
FailoverManager.SetHostList(dnsSrvRecords.ConvertAll(r => new FailoverServer(r.Target, r.Port, null)),
FailoverMethod.Sequential);
}
else
FailoverManager.ParseHostList(Settings.Server, false);
}
// Load balancing && Failover
if (ReplicationManager.IsReplicationGroup(Settings.Server))
{
if (driver == null)
{
await ReplicationManager.GetNewConnectionAsync(Settings.Server, false, this, execAsync, cancellationToken).ConfigureAwait(false);
}
else
currentSettings = driver.Settings;
}
else if (FailoverManager.FailoverGroup != null && !Settings.Pooling)
{
string connectionString = await FailoverManager.AttemptConnectionAsync(this, Settings.ConnectionString, execAsync, cancellationToken);
currentSettings.ConnectionString = connectionString;
}
if (Settings.Pooling)
{
if (FailoverManager.FailoverGroup != null)
{
string connectionString = await FailoverManager.AttemptConnectionAsync(this, Settings.ConnectionString, execAsync, cancellationToken, true);
currentSettings.ConnectionString = connectionString;
}
#if NET5_0_OR_GREATER
currentActivity = MySQLActivitySource.OpenPooledConnection(currentSettings);
#endif
MySqlPool pool = await MySqlPoolManager.GetPoolAsync(currentSettings, execAsync, cancellationToken).ConfigureAwait(false);
if (driver == null || !driver.IsOpen)
driver = await pool.GetConnectionAsync(execAsync, cancellationToken).ConfigureAwait(false);
ProcedureCache = pool.ProcedureCache;
}
else
{
if (driver == null || !driver.IsOpen)
{
#if NET5_0_OR_GREATER
currentActivity = MySQLActivitySource.OpenConnection(currentSettings);
#endif
driver = await Driver.CreateAsync(currentSettings, execAsync, cancellationToken).ConfigureAwait(false);
}
ProcedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize);
}
}
catch (Exception ex)
{
#if NET5_0_OR_GREATER
MySQLActivitySource.SetException(currentActivity, ex);
#endif
SetState(ConnectionState.Closed, true);
throw;
}
SetState(ConnectionState.Open, false);
await driver.ConfigureAsync(this, execAsync, cancellationToken).ConfigureAwait(false);
if (driver.IsPasswordExpired && Settings.Pooling)
await MySqlPoolManager.ClearPoolAsync(currentSettings, execAsync).ConfigureAwait(false);
if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired))
{
if (!string.IsNullOrEmpty(Settings.Database))
await ChangeDatabaseAsync(Settings.Database, execAsync, cancellationToken).ConfigureAwait(false);
}
// setup our schema provider
_schemaProvider = new ISSchemaProvider(this);
PerfMonitor = new PerformanceMonitor(this);
// if we are opening up inside a current transaction, then autoenlist
// TODO: control this with a connection string option
if (Transaction.Current != null && Settings.AutoEnlist)
EnlistTransaction(Transaction.Current);
hasBeenOpen = true;
SetState(ConnectionState.Open, true);
}