/// <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; } }
/// <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; } 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); }