/// <summary> /// Ends the transaction scope. /// </summary> /// <exception cref="InvalidOperationException">A thread other than the creating thread /// is disposing the object.</exception> /// <remarks> /// See <Typ>LearningStoreTransactionScope</Typ> for more information. /// </remarks> public void Dispose() { // Skip if already disposed if (m_disposed) { return; } // Fail if this is being called on a different thread if (m_scopeThread != Thread.CurrentThread) { throw new InvalidOperationException(LearningStoreStrings.ScopeDisposedInInvalidThread); } if (m_nextScope != null) { // There are scopes "above" this one -- which means the user called // Dispose out-of-order. // First dispose the scope(s) above this one m_nextScope.Dispose(); if (m_nextScope != null) { throw new LearningComponentsInternalException("LSTR3100"); } if (s_currentScope != this) { throw new LearningComponentsInternalException("LSTR3110"); } } // Leave the scope if (m_priorScope != null) { m_priorScope.m_nextScope = null; } s_currentScope = m_priorScope; // Mark as disposed m_disposed = true; // Dispose the connections if necessary if (m_createdConnections != null) { foreach (SqlConnection connection in m_createdConnections.Values) { connection.Dispose(); } m_createdConnections.Clear(); } try { // Handle the dependent transaction if necessary if (m_dependentTransaction != null) { if (m_complete) { m_dependentTransaction.Complete(); } else { m_dependentTransaction.Rollback(); } } // Handle the committable transaction if necessary if (m_committableTransaction != null) { if (m_complete) { m_committableTransaction.Commit(); } else { m_committableTransaction.Rollback(); } } } finally { if (m_dependentTransaction != null) { m_dependentTransaction.Dispose(); } if (m_committableTransaction != null) { m_committableTransaction.Dispose(); } } }