/// <summary> /// Closes the transaction. Behaviour is different for root scope, owning scope & child scope. /// </summary> private void CloseTransaction() { // indicate local scope has closed txn _scopeHasOpenTransaction = false; // owning scope needs to do extra if (_scopeOwnsTransaction) { // dispose transaction and remove from root scope if (_transaction != null) { _transaction.DangerousInternalTransaction.Dispose(); _transaction = null; RootScope._transaction = null; } // clear rollback flag _voteRollback = false; RootScope._voteRollback = false; // reset flags to allow consequtive txn's _scopeOwnsTransaction = false; _transactionOwner = null; RootScope._transactionOwner = null; } }
internal DACScope(IDAC dac, ScopeContextPolicy policy, bool openConnection, string contextPrefix = DefaultContextPrefix, Auto?autoAction = null) : base(string.Format(ContextNameTemplate, contextPrefix, dac.ConnectionString), policy) { if (dac == null) { throw new ArgumentNullException("dac"); } DAC = dac; if (IsRootScope) { _connection = new RestrictedConnection(DAC.CreateConnection()); if (openConnection) { _connection.Open(); } _scopeOwnsConnection = true; _transaction = null; _scopeOwnsTransaction = false; _transactionOwner = null; } else { if (RootScope._connection == null) { throw new SoftwareException("Internal Error: RootScope DAC had null connection"); } _connection = RootScope._connection; _transaction = RootScope._transaction; _transactionOwner = RootScope._transactionOwner; _scopeOwnsTransaction = false; _scopeOwnsConnection = false; if (openConnection && _connection.State.IsIn(ConnectionState.Closed, ConnectionState.Broken)) { _connection.Open(); } } _withinSystemTransactionScope = System.Transactions.Transaction.Current != null; if (_scopeOwnsConnection && _withinSystemTransactionScope) { DAC.EnlistInSystemTransaction(_connection.DangerousInternalConnection, System.Transactions.Transaction.Current); } _voteRollback = false; _scopeHasOpenTransaction = false; _autoAction = autoAction; }
public void BeginTransaction(IsolationLevel?isolationLevel = null) { if (isolationLevel == null) { isolationLevel = DAC.DefaultIsolationLevel; } if (_withinSystemTransactionScope) { _withinSystemTransactionScope = System.Transactions.Transaction.Current != null; // may have been removed if (_withinSystemTransactionScope) { throw new SoftwareException("DACScope transactions cannot be used a System.Transactions.TransactionScope."); } } if (_transaction == null) { _transaction = _connection.BeginTransactionInternal(isolationLevel.Value); _scopeOwnsTransaction = true; _transactionOwner = this; // make sure child scopes can see this transaction and owner by placing it in rootscope (cleaned up on exit) RootScope._transaction = _transaction; RootScope._transactionOwner = this; } else { // if this is the parent scope, error if (_scopeOwnsTransaction) { throw new SoftwareException("Scope has already created a transaction"); } // parent scope already defined a transaction, so use it if (isolationLevel.Value > _transaction.IsolationLevel) { throw new SoftwareException("A transaction already exists with lower isolation level. Requested = {0}, Current = {1}", isolationLevel, _transaction.IsolationLevel); } _scopeOwnsTransaction = false; } _scopeHasOpenTransaction = true; }