Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Data / System / Data / SqlClient / SqlTransaction.cs / 1 / SqlTransaction.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data.SqlClient { using System.Data; using System.Data.Common; using System.Data.ProviderBase; using System.Data.Sql; using System.Data.SqlTypes; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Threading; #if WINFSInternalOnly internal #else public #endif sealed class SqlTransaction : DbTransaction { private static int _objectTypeCount; // Bid counter internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); internal readonly IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted; private SqlInternalTransaction _internalTransaction; private SqlConnection _connection; private bool _isFromAPI; internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con, IsolationLevel iso, SqlInternalTransaction internalTransaction) { SqlConnection.VerifyExecutePermission(); _isolationLevel = iso; _connection = con; if (internalTransaction == null) { _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this); } else { Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!"); _internalTransaction = internalTransaction; _internalTransaction.InitParent(this); } } //////////////////////////////////////////////////////////////////////////////////////// // PROPERTIES //////////////////////////////////////////////////////////////////////////////////////// new public SqlConnection Connection { // MDAC 66655 get { if (IsZombied) { return null; } else { return _connection; } } } override protected DbConnection DbConnection { get { return Connection; } } internal SqlInternalTransaction InternalTransaction { get { return _internalTransaction; } } override public IsolationLevel IsolationLevel { get { ZombieCheck(); return _isolationLevel; } } private bool IsYukonPartialZombie { get { return (null != _internalTransaction && _internalTransaction.IsCompleted); } } internal bool IsZombied { get { return (null == _internalTransaction || _internalTransaction.IsCompleted); } } internal int ObjectID { get { return _objectID; } } internal SqlStatistics Statistics { get { if (null != _connection) { if (_connection.StatisticsEnabled) { return _connection.Statistics; } } return null; } } //////////////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////////////// override public void Commit() { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, "%d#", ObjectID); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Commit(); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } protected override void Dispose(bool disposing) { if (disposing) { SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); if (!IsZombied && !IsYukonPartialZombie) { _internalTransaction.Dispose(); } #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } } base.Dispose(disposing); } override public void Rollback() { if (IsYukonPartialZombie) { // Put something in the trace in case a customer has an issue if (Bid.AdvancedOn) { Bid.Trace(" %d# partial zombie no rollback required\n", ObjectID); } _internalTransaction = null; // yukon zombification } else { ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#", ObjectID); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } } public void Rollback(string transactionName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d# transactionName='%ls'", ObjectID, transactionName); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(transactionName); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } public void Save(string savePointName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d# savePointName='%ls'", ObjectID, savePointName); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _internalTransaction.Save(savePointName); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } //////////////////////////////////////////////////////////////////////////////////////// // INTERNAL METHODS //////////////////////////////////////////////////////////////////////////////////////// internal void Zombie() { // SQLBUDT #402544 For Yukon, we have to defer "zombification" until // we get past the users' next rollback, else we'll // throw an exception there that is a breaking change. // Of course, if the connection is aready closed, // then we're free to zombify... SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection); if (null != internalConnection && internalConnection.IsYukonOrNewer && !_isFromAPI) { if (Bid.AdvancedOn) { Bid.Trace(" %d# yukon deferred zombie\n", ObjectID); } } else { _internalTransaction = null; // pre-yukon zombification } } //////////////////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS //////////////////////////////////////////////////////////////////////////////////////// private void ZombieCheck() { // If this transaction has been completed, throw exception since it is unusable. if (IsZombied) { if (IsYukonPartialZombie) { _internalTransaction = null; // yukon zombification } throw ADP.TransactionZombied(this); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data.SqlClient { using System.Data; using System.Data.Common; using System.Data.ProviderBase; using System.Data.Sql; using System.Data.SqlTypes; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Threading; #if WINFSInternalOnly internal #else public #endif sealed class SqlTransaction : DbTransaction { private static int _objectTypeCount; // Bid counter internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); internal readonly IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted; private SqlInternalTransaction _internalTransaction; private SqlConnection _connection; private bool _isFromAPI; internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con, IsolationLevel iso, SqlInternalTransaction internalTransaction) { SqlConnection.VerifyExecutePermission(); _isolationLevel = iso; _connection = con; if (internalTransaction == null) { _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this); } else { Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!"); _internalTransaction = internalTransaction; _internalTransaction.InitParent(this); } } //////////////////////////////////////////////////////////////////////////////////////// // PROPERTIES //////////////////////////////////////////////////////////////////////////////////////// new public SqlConnection Connection { // MDAC 66655 get { if (IsZombied) { return null; } else { return _connection; } } } override protected DbConnection DbConnection { get { return Connection; } } internal SqlInternalTransaction InternalTransaction { get { return _internalTransaction; } } override public IsolationLevel IsolationLevel { get { ZombieCheck(); return _isolationLevel; } } private bool IsYukonPartialZombie { get { return (null != _internalTransaction && _internalTransaction.IsCompleted); } } internal bool IsZombied { get { return (null == _internalTransaction || _internalTransaction.IsCompleted); } } internal int ObjectID { get { return _objectID; } } internal SqlStatistics Statistics { get { if (null != _connection) { if (_connection.StatisticsEnabled) { return _connection.Statistics; } } return null; } } //////////////////////////////////////////////////////////////////////////////////////// // PUBLIC METHODS //////////////////////////////////////////////////////////////////////////////////////// override public void Commit() { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, "%d#", ObjectID); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Commit(); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } protected override void Dispose(bool disposing) { if (disposing) { SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); if (!IsZombied && !IsYukonPartialZombie) { _internalTransaction.Dispose(); } #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } } base.Dispose(disposing); } override public void Rollback() { if (IsYukonPartialZombie) { // Put something in the trace in case a customer has an issue if (Bid.AdvancedOn) { Bid.Trace(" %d# partial zombie no rollback required\n", ObjectID); } _internalTransaction = null; // yukon zombification } else { ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d#", ObjectID); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } } public void Rollback(string transactionName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d# transactionName='%ls'", ObjectID, transactionName); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _isFromAPI = true; _internalTransaction.Rollback(transactionName); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { _isFromAPI = false; SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } public void Save(string savePointName) { SqlConnection.ExecutePermission.Demand(); // MDAC 81476 ZombieCheck(); SqlStatistics statistics = null; IntPtr hscp; Bid.ScopeEnter(out hscp, " %d# savePointName='%ls'", ObjectID, savePointName); SNIHandle bestEffortCleanupTarget = null; RuntimeHelpers.PrepareConstrainedRegions(); try { #if DEBUG object initialReliabilitySlotValue = Thread.GetData(TdsParser.ReliabilitySlot); RuntimeHelpers.PrepareConstrainedRegions(); try { Thread.SetData(TdsParser.ReliabilitySlot, true); #endif //DEBUG bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection); statistics = SqlStatistics.StartTimer(Statistics); _internalTransaction.Save(savePointName); #if DEBUG } finally { Thread.SetData(TdsParser.ReliabilitySlot, initialReliabilitySlotValue); } #endif //DEBUG } catch (System.OutOfMemoryException e) { _connection.Abort(e); throw; } catch (System.StackOverflowException e) { _connection.Abort(e); throw; } catch (System.Threading.ThreadAbortException e) { _connection.Abort(e); SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } finally { SqlStatistics.StopTimer(statistics); Bid.ScopeLeave(ref hscp); } } //////////////////////////////////////////////////////////////////////////////////////// // INTERNAL METHODS //////////////////////////////////////////////////////////////////////////////////////// internal void Zombie() { // SQLBUDT #402544 For Yukon, we have to defer "zombification" until // we get past the users' next rollback, else we'll // throw an exception there that is a breaking change. // Of course, if the connection is aready closed, // then we're free to zombify... SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection); if (null != internalConnection && internalConnection.IsYukonOrNewer && !_isFromAPI) { if (Bid.AdvancedOn) { Bid.Trace(" %d# yukon deferred zombie\n", ObjectID); } } else { _internalTransaction = null; // pre-yukon zombification } } //////////////////////////////////////////////////////////////////////////////////////// // PRIVATE METHODS //////////////////////////////////////////////////////////////////////////////////////// private void ZombieCheck() { // If this transaction has been completed, throw exception since it is unusable. if (IsZombied) { if (IsYukonPartialZombie) { _internalTransaction = null; // yukon zombification } throw ADP.TransactionZombied(this); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- JavaScriptSerializer.cs
- ListViewCancelEventArgs.cs
- WriteTimeStream.cs
- StringExpressionSet.cs
- StringBuilder.cs
- ColorConverter.cs
- TypeBinaryExpression.cs
- DefaultParameterValueAttribute.cs
- Membership.cs
- AddingNewEventArgs.cs
- SchemaNamespaceManager.cs
- FixedElement.cs
- FactoryId.cs
- HostProtectionPermission.cs
- BaseCollection.cs
- XmlSchemaException.cs
- DataConnectionHelper.cs
- DrawingContextWalker.cs
- IndependentlyAnimatedPropertyMetadata.cs
- BinaryMessageFormatter.cs
- ContentFileHelper.cs
- WindowsGraphicsCacheManager.cs
- EmbossBitmapEffect.cs
- ListBindingConverter.cs
- CrossSiteScriptingValidation.cs
- ServiceReference.cs
- ObjectDataSource.cs
- XmlArrayAttribute.cs
- NoResizeHandleGlyph.cs
- WinEventTracker.cs
- HttpConfigurationSystem.cs
- ObjRef.cs
- BitmapEffectDrawingContent.cs
- ToolStripStatusLabel.cs
- Package.cs
- EntityTypeBase.cs
- ThrowHelper.cs
- XmlSchemaAnnotation.cs
- SafeLibraryHandle.cs
- ListViewSelectEventArgs.cs
- ParamArrayAttribute.cs
- ConversionHelper.cs
- DecoderFallbackWithFailureFlag.cs
- XsltArgumentList.cs
- Trace.cs
- TypeNameHelper.cs
- IImplicitResourceProvider.cs
- SqlCaseSimplifier.cs
- DocumentXPathNavigator.cs
- PeerMaintainer.cs
- SapiAttributeParser.cs
- TTSVoice.cs
- DataGridAddNewRow.cs
- ExtensionFile.cs
- MimeBasePart.cs
- BindingContext.cs
- HttpModulesSection.cs
- ToolboxComponentsCreatingEventArgs.cs
- DataGridViewRow.cs
- RewritingValidator.cs
- Crypto.cs
- Stroke2.cs
- XmlBinaryWriter.cs
- XmlValidatingReaderImpl.cs
- MailAddress.cs
- SyndicationDeserializer.cs
- ChannelCredentials.cs
- StylusPoint.cs
- InternalBufferOverflowException.cs
- CryptoApi.cs
- FileInfo.cs
- PropertyEmitter.cs
- glyphs.cs
- ControlUtil.cs
- PolyQuadraticBezierSegment.cs
- IDictionary.cs
- TagMapInfo.cs
- MarkupProperty.cs
- CustomErrorsSection.cs
- SqlInternalConnection.cs
- ImageSourceValueSerializer.cs
- HtmlInputText.cs
- UndirectedGraph.cs
- AppSettingsReader.cs
- SubpageParagraph.cs
- ResourceExpressionBuilder.cs
- CodeVariableDeclarationStatement.cs
- MasterPage.cs
- ComplexTypeEmitter.cs
- XmlHierarchyData.cs
- CodePropertyReferenceExpression.cs
- TextBox.cs
- IntPtr.cs
- StoryFragments.cs
- EventListener.cs
- BindValidator.cs
- ComponentRenameEvent.cs
- ArrangedElement.cs
- TranslateTransform3D.cs
- AdjustableArrowCap.cs