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
- SemanticResolver.cs
- PopupControlService.cs
- ReadOnlyPermissionSet.cs
- DocumentAutomationPeer.cs
- Context.cs
- FormViewActionList.cs
- FontNamesConverter.cs
- Soap12ProtocolImporter.cs
- GlyphingCache.cs
- PathTooLongException.cs
- DefaultSerializationProviderAttribute.cs
- NameValueConfigurationCollection.cs
- SByteStorage.cs
- InstanceCreationEditor.cs
- MatrixCamera.cs
- ViewManager.cs
- MailBnfHelper.cs
- ProtectedProviderSettings.cs
- CacheMemory.cs
- AsyncOperation.cs
- XmlAutoDetectWriter.cs
- DbDataRecord.cs
- MenuCommands.cs
- AccessDataSource.cs
- ImageSourceValueSerializer.cs
- WindowsEditBoxRange.cs
- CellConstant.cs
- cookiecollection.cs
- IdnElement.cs
- PermissionRequestEvidence.cs
- ContainerControlDesigner.cs
- DiagnosticsElement.cs
- IteratorDescriptor.cs
- ListViewItem.cs
- LiteralControl.cs
- NamespaceEmitter.cs
- SessionSwitchEventArgs.cs
- StringFunctions.cs
- XmlNavigatorStack.cs
- XmlAttribute.cs
- TraceSwitch.cs
- MatrixAnimationUsingPath.cs
- DocumentXmlWriter.cs
- As.cs
- ApplicationHost.cs
- GetPageNumberCompletedEventArgs.cs
- TemplateDefinition.cs
- ClientSponsor.cs
- FixedSchema.cs
- DBConcurrencyException.cs
- CoreSwitches.cs
- SpellerError.cs
- path.cs
- WebExceptionStatus.cs
- WebServiceBindingAttribute.cs
- ReadContentAsBinaryHelper.cs
- SQLInt16Storage.cs
- ReturnValue.cs
- XmlNodeChangedEventArgs.cs
- XmlSchemaInclude.cs
- ContentPlaceHolderDesigner.cs
- ISAPIApplicationHost.cs
- securestring.cs
- XmlNullResolver.cs
- SqlPersonalizationProvider.cs
- OdbcConnectionString.cs
- ListViewInsertionMark.cs
- SafeReversePInvokeHandle.cs
- CSharpCodeProvider.cs
- DataGridColumn.cs
- RegionInfo.cs
- Journal.cs
- Rect.cs
- Part.cs
- SecurityManager.cs
- OdbcEnvironment.cs
- DependencyObject.cs
- SQLByteStorage.cs
- DataSourceXmlElementAttribute.cs
- ConfigurationCollectionAttribute.cs
- SRef.cs
- TextureBrush.cs
- WebPartTracker.cs
- RevocationPoint.cs
- TableLayoutColumnStyleCollection.cs
- OdbcConnectionOpen.cs
- HtmlTextArea.cs
- DataColumnMapping.cs
- SocketException.cs
- Soap12ProtocolImporter.cs
- PeerApplicationLaunchInfo.cs
- XmlSchemaNotation.cs
- PictureBoxDesigner.cs
- TransformConverter.cs
- UserControlParser.cs
- DataRecord.cs
- WorkflowInstanceSuspendedRecord.cs
- safemediahandle.cs
- WebPartCatalogAddVerb.cs
- DetailsViewAutoFormat.cs