public void Rollback(SinglePhaseEnlistment singlePhaseEnlistment) { // prevent commands in main thread to run concurrently Driver driver = connection.driver; lock (driver) { rollbackThreadId = Thread.CurrentThread.ManagedThreadId; while (connection.Reader != null) { // wait for reader to finish. Maybe we should not wait // forever and cancel it after some time? System.Threading.Thread.Sleep(100); } simpleTransaction.Rollback(); singlePhaseEnlistment.Aborted(); DriverTransactionManager.RemoveDriverInTransaction(baseTransaction); driver.currentTransaction = null; if (connection.State == ConnectionState.Closed) { connection.CloseFully(); } rollbackThreadId = 0; } }
/// <summary> /// Enlists in the specified transaction. /// </summary> /// <param name="transaction"> /// A reference to an existing <see cref="System.Transactions.Transaction"/> in which to enlist. /// </param> public override void EnlistTransaction(Transaction transaction) { // enlisting in the null transaction is a noop if (transaction == null) { return; } // guard against trying to enlist in more than one transaction if (driver.CurrentTransaction != null) { if (driver.CurrentTransaction.BaseTransaction == transaction) { return; } Throw(new MySqlException("Already enlisted")); } // now see if we need to swap out drivers. We would need to do this since // we have to make sure all ops for a given transaction are done on the // same physical connection. Driver existingDriver = DriverTransactionManager.GetDriverInTransaction(transaction); if (existingDriver != null) { // we can't allow more than one driver to contribute to the same connection if (existingDriver.IsInActiveUse) { Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported)); } // there is an existing driver and it's not being currently used. // now we need to see if it is using the same connection string string text1 = existingDriver.Settings.ConnectionString; string text2 = Settings.ConnectionString; if (String.Compare(text1, text2, true) != 0) { Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported)); } // close existing driver // set this new driver as our existing driver CloseFully(); driver = existingDriver; } if (driver.CurrentTransaction == null) { MySqlPromotableTransaction t = new MySqlPromotableTransaction(this, transaction); if (!transaction.EnlistPromotableSinglePhase(t)) { Throw(new NotSupportedException(Resources.DistributedTxnNotSupported)); } driver.CurrentTransaction = t; DriverTransactionManager.SetDriverInTransaction(driver); driver.IsInActiveUse = true; } }
public void SinglePhaseCommit(SinglePhaseEnlistment singlePhaseEnlistment) { simpleTransaction.Commit(); singlePhaseEnlistment.Committed(); DriverTransactionManager.RemoveDriverInTransaction(baseTransaction); connection.driver.CurrentTransaction = null; if (connection.State == ConnectionState.Closed) connection.CloseFully(); }
void IPromotableSinglePhaseNotification.Rollback(SinglePhaseEnlistment singlePhaseEnlistment) { simpleTransaction.Rollback(); singlePhaseEnlistment.Aborted(); DriverTransactionManager.RemoveDriverInTransaction(baseTransaction); connection.driver.CurrentTransaction = null; if (connection.State == ConnectionState.Closed) { connection.CloseFully(); } }
public override void EnlistTransaction(Transaction transaction) { if (transaction == null) { return; } if (this.driver.CurrentTransaction != null) { if (this.driver.CurrentTransaction.BaseTransaction == transaction) { return; } this.Throw(new MySqlException("Already enlisted")); } Driver driverInTransaction = DriverTransactionManager.GetDriverInTransaction(transaction); if (driverInTransaction != null) { if (driverInTransaction.IsInActiveUse) { this.Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported)); } string connectionString = driverInTransaction.Settings.ConnectionString; string connectionString2 = this.Settings.ConnectionString; if (string.Compare(connectionString, connectionString2, true) != 0) { this.Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported)); } this.CloseFully(); this.driver = driverInTransaction; } if (this.driver.CurrentTransaction == null) { MySqlPromotableTransaction mySqlPromotableTransaction = new MySqlPromotableTransaction(this, transaction); if (!transaction.EnlistPromotableSinglePhase(mySqlPromotableTransaction)) { this.Throw(new NotSupportedException(Resources.DistributedTxnNotSupported)); } this.driver.CurrentTransaction = mySqlPromotableTransaction; DriverTransactionManager.SetDriverInTransaction(this.driver); this.driver.IsInActiveUse = true; } }
public void Rollback(SinglePhaseEnlistment singlePhaseEnlistment) { Driver driver = this.connection.driver; lock (driver) { this.rollbackThreadId = Thread.CurrentThread.ManagedThreadId; while (this.connection.Reader != null) { Thread.Sleep(100); } this.simpleTransaction.Rollback(); singlePhaseEnlistment.Aborted(); DriverTransactionManager.RemoveDriverInTransaction(this.baseTransaction); driver.CurrentTransaction = null; if (this.connection.State == ConnectionState.Closed) { this.connection.CloseFully(); } this.rollbackThreadId = 0; } }
/// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/> public override void Open() { if (State == ConnectionState.Open) { Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen)); } // start up our interceptors _exceptionInterceptor = new ExceptionInterceptor(this); commandInterceptor = new CommandInterceptor(this); SetState(ConnectionState.Connecting, true); #if !NETSTANDARD1_3 AssertPermissions(); //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)); } } #endif try { MySqlConnectionStringBuilder currentSettings = Settings; //TODO: SUPPORT FOR 452 AND 46X // Load balancing #if !NETSTANDARD1_3 if (ReplicationManager.IsReplicationGroup(Settings.Server)) { if (driver == null) { ReplicationManager.GetNewConnection(Settings.Server, false, this); } else { currentSettings = driver.Settings; } } #endif if (Settings.Pooling) { MySqlPool pool = MySqlPoolManager.GetPool(currentSettings); if (driver == null || !driver.IsOpen) { driver = pool.GetConnection(); } ProcedureCache = pool.ProcedureCache; } else { if (driver == null || !driver.IsOpen) { driver = Driver.Create(currentSettings); } ProcedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize); } } catch (Exception) { SetState(ConnectionState.Closed, true); throw; } SetState(ConnectionState.Open, false); driver.Configure(this); if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired)) { if (!string.IsNullOrEmpty(Settings.Database)) { ChangeDatabase(Settings.Database); } } // 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 !NETSTANDARD1_3 if (Transaction.Current != null && Settings.AutoEnlist) { EnlistTransaction(Transaction.Current); } #endif hasBeenOpen = true; SetState(ConnectionState.Open, true); }
public override void Open() { if (this.State == ConnectionState.Open) { this.Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen)); } this.exceptionInterceptor = new ExceptionInterceptor(this); this.commandInterceptor = new CommandInterceptor(this); this.SetState(ConnectionState.Connecting, true); this.AssertPermissions(); if (this.Settings.AutoEnlist && Transaction.Current != null) { this.driver = DriverTransactionManager.GetDriverInTransaction(Transaction.Current); if (this.driver != null && (this.driver.IsInActiveUse || !this.driver.Settings.EquivalentTo(this.Settings))) { this.Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported)); } } try { MySqlConnectionStringBuilder settings = this.Settings; if (ReplicationManager.IsReplicationGroup(this.Settings.Server)) { if (this.driver == null) { ReplicationManager.GetNewConnection(this.Settings.Server, false, this); return; } settings = this.driver.Settings; } if (this.Settings.Pooling) { MySqlPool pool = MySqlPoolManager.GetPool(settings); if (this.driver == null || !this.driver.IsOpen) { this.driver = pool.GetConnection(); } this.procedureCache = pool.ProcedureCache; } else { if (this.driver == null || !this.driver.IsOpen) { this.driver = Driver.Create(settings); } this.procedureCache = new ProcedureCache((int)this.Settings.ProcedureCacheSize); } } catch (Exception) { this.SetState(ConnectionState.Closed, true); throw; } if (this.driver.Settings.UseOldSyntax) { MySqlTrace.LogWarning(this.ServerThread, "You are using old syntax that will be removed in future versions"); } this.SetState(ConnectionState.Open, false); this.driver.Configure(this); if ((!this.driver.SupportsPasswordExpiration || !this.driver.IsPasswordExpired) && this.Settings.Database != null && this.Settings.Database != string.Empty) { this.ChangeDatabase(this.Settings.Database); } this.schemaProvider = new ISSchemaProvider(this); this.perfMonitor = new PerformanceMonitor(this); if (Transaction.Current != null && this.Settings.AutoEnlist) { this.EnlistTransaction(Transaction.Current); } this.hasBeenOpen = true; this.SetState(ConnectionState.Open, true); }
/// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/> public override void Open() { if (State == ConnectionState.Open) { Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen)); } #if !RT // start up our interceptors exceptionInterceptor = new ExceptionInterceptor(this); commandInterceptor = new CommandInterceptor(this); #endif SetState(ConnectionState.Connecting, true); AssertPermissions(); #if !RT // 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)); } } #endif try { MySqlConnectionStringBuilder currentSettings = Settings; // Load balancing if (ReplicationManager.IsReplicationGroup(Settings.Server)) { if (driver == null) { ReplicationManager.GetNewConnection(Settings.Server, false, this); } else { currentSettings = driver.Settings; } } if (Settings.Pooling) { MySqlPool pool = MySqlPoolManager.GetPool(currentSettings); if (driver == null || !driver.IsOpen) { driver = pool.GetConnection(); } procedureCache = pool.ProcedureCache; } else { if (driver == null || !driver.IsOpen) { driver = Driver.Create(currentSettings); } procedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize); } } catch (Exception ex) { SetState(ConnectionState.Closed, true); throw; } // if the user is using old syntax, let them know if (driver.Settings.UseOldSyntax) { MySqlTrace.LogWarning(ServerThread, "You are using old syntax that will be removed in future versions"); } SetState(ConnectionState.Open, false); driver.Configure(this); if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired)) { if (Settings.Database != null && Settings.Database != String.Empty) { ChangeDatabase(Settings.Database); } } // 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 !MONO && !RT if (Transaction.Current != null && Settings.AutoEnlist) { EnlistTransaction(Transaction.Current); } #endif hasBeenOpen = true; SetState(ConnectionState.Open, true); }
/// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/> public override void Open() { if (State == ConnectionState.Open) { throw new InvalidOperationException(Resources.ConnectionAlreadyOpen); } SetState(ConnectionState.Connecting, true); #if !CF // 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); } } #endif try { if (settings.Pooling) { MySqlPool pool = MySqlPoolManager.GetPool(settings); if (driver == null || !driver.IsOpen) { driver = pool.GetConnection(); } procedureCache = pool.ProcedureCache; } else { if (driver == null || !driver.IsOpen) { driver = Driver.Create(settings); } procedureCache = new ProcedureCache((int)settings.ProcedureCacheSize); } } catch (Exception) { SetState(ConnectionState.Closed, true); throw; } // if the user is using old syntax, let them know if (driver.Settings.UseOldSyntax) { MySqlTrace.LogWarning(ServerThread, "You are using old syntax that will be removed in future versions"); } SetState(ConnectionState.Open, false); driver.Configure(this); if (settings.Database != null && settings.Database != String.Empty) { ChangeDatabase(settings.Database); } // setup our schema provider schemaProvider = new ISSchemaProvider(this); #if !CF perfMonitor = new PerformanceMonitor(this); #endif // if we are opening up inside a current transaction, then autoenlist // TODO: control this with a connection string option #if !MONO && !CF if (Transaction.Current != null && settings.AutoEnlist) { EnlistTransaction(Transaction.Current); } #endif hasBeenOpen = true; SetState(ConnectionState.Open, true); }
/// <include file='docs/MySqlConnection.xml' path='docs/Open/*'/> public override void Open() { if (State == ConnectionState.Open) { Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen)); } // start up our interceptors _exceptionInterceptor = new ExceptionInterceptor(this); commandInterceptor = new CommandInterceptor(this); SetState(ConnectionState.Connecting, true); AssertPermissions(); //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.ConnectionProtocol == MySqlConnectionProtocol.Tcp && Settings.IsSshEnabled()) { _sshHandler = new Ssh( Settings.SshHostName, Settings.SshUserName, Settings.SshPassword, Settings.SshKeyFile, Settings.SshPassphrase, Settings.SshPort, Settings.Server, Settings.Port, false ); _sshHandler.StartClient(); } if (!Settings.Pooling || MySqlPoolManager.Hosts == null) { FailoverManager.Reset(); if (Settings.DnsSrv) { var dnsSrvRecords = DnsResolver.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) { ReplicationManager.GetNewConnection(Settings.Server, false, this); } else { currentSettings = driver.Settings; } } else if (FailoverManager.FailoverGroup != null && !Settings.Pooling) { FailoverManager.AttemptConnection(this, Settings.ConnectionString, out string connectionString); currentSettings.ConnectionString = connectionString; } if (Settings.Pooling) { if (FailoverManager.FailoverGroup != null) { FailoverManager.AttemptConnection(this, Settings.ConnectionString, out string connectionString, true); currentSettings.ConnectionString = connectionString; } MySqlPool pool = MySqlPoolManager.GetPool(currentSettings); if (driver == null || !driver.IsOpen) { driver = pool.GetConnection(); } ProcedureCache = pool.ProcedureCache; } else { if (driver == null || !driver.IsOpen) { driver = Driver.Create(currentSettings); } ProcedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize); } } catch (Exception) { SetState(ConnectionState.Closed, true); throw; } SetState(ConnectionState.Open, false); driver.Configure(this); if (driver.IsPasswordExpired && Settings.Pooling) { MySqlPoolManager.ClearPool(currentSettings); } if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired)) { if (!string.IsNullOrEmpty(Settings.Database)) { ChangeDatabase(Settings.Database); } } // 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); }