Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Data / System / Data / SqlClient / SqlTransaction.cs / 2 / 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
- XPathAncestorQuery.cs
- EntityCollection.cs
- ReadOnlyDataSource.cs
- odbcmetadatacollectionnames.cs
- UnaryNode.cs
- TabletDeviceInfo.cs
- ObjectDataSourceDesigner.cs
- Attributes.cs
- _DigestClient.cs
- SystemTcpConnection.cs
- Module.cs
- ApplicationProxyInternal.cs
- SqlCommand.cs
- ConnectionInterfaceCollection.cs
- OneOfScalarConst.cs
- Command.cs
- RecommendedAsConfigurableAttribute.cs
- DynamicContractTypeBuilder.cs
- TrackBarRenderer.cs
- TextDecorations.cs
- SqlTrackingWorkflowInstance.cs
- CustomLineCap.cs
- SafeFreeMibTable.cs
- Maps.cs
- ObjectHandle.cs
- SapiRecoInterop.cs
- Token.cs
- RectValueSerializer.cs
- SchemaTypeEmitter.cs
- MemberHolder.cs
- PasswordBoxAutomationPeer.cs
- PenThreadPool.cs
- hresults.cs
- HtmlTable.cs
- BasicExpressionVisitor.cs
- ADRoleFactory.cs
- NavigationPropertyEmitter.cs
- FormClosedEvent.cs
- DbProviderFactory.cs
- ProgressBar.cs
- SystemWebCachingSectionGroup.cs
- DesignerForm.cs
- SafeViewOfFileHandle.cs
- SelectedCellsChangedEventArgs.cs
- SafeNativeMethodsCLR.cs
- DoubleAnimationUsingKeyFrames.cs
- LoginCancelEventArgs.cs
- HtmlHead.cs
- QilLoop.cs
- TypeConvertions.cs
- ConnectionStringsSection.cs
- SafeLibraryHandle.cs
- PropertyValueUIItem.cs
- Cell.cs
- Timer.cs
- NativeMethods.cs
- NumberAction.cs
- FontFamily.cs
- ProcessHostMapPath.cs
- SqlConnectionStringBuilder.cs
- QilInvokeLateBound.cs
- QueryExecutionOption.cs
- PathGeometry.cs
- MethodExpression.cs
- graph.cs
- UdpTransportSettingsElement.cs
- XsdBuilder.cs
- NativeBuffer.cs
- DefinitionUpdate.cs
- TextProviderWrapper.cs
- SqlConnectionStringBuilder.cs
- ArrangedElementCollection.cs
- DirectoryObjectSecurity.cs
- _SslStream.cs
- ActivityCodeDomReferenceService.cs
- ThemeableAttribute.cs
- SecurityChannelListener.cs
- FixedDSBuilder.cs
- WebCategoryAttribute.cs
- TableColumn.cs
- SafeReversePInvokeHandle.cs
- HttpListenerException.cs
- TextAnchor.cs
- SoapElementAttribute.cs
- EndOfStreamException.cs
- DataSetMappper.cs
- GenericRootAutomationPeer.cs
- StagingAreaInputItem.cs
- ComponentEditorPage.cs
- NetPeerTcpBindingElement.cs
- StrongNameMembershipCondition.cs
- SqlBuffer.cs
- BaseWebProxyFinder.cs
- JournalEntry.cs
- Perspective.cs
- PropertyValueChangedEvent.cs
- XmlReflectionMember.cs
- GeneralTransform3D.cs
- RootBuilder.cs
- DefaultTextStoreTextComposition.cs