Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / OleDb / OleDbTransaction.cs / 1305376 / OleDbTransaction.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
// [....]
//-----------------------------------------------------------------------------
namespace System.Data.OleDb {
using System.Data;
using System.Data.Common;
using System.Data.ProviderBase;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Threading;
public sealed class OleDbTransaction : DbTransaction {
private readonly OleDbTransaction _parentTransaction; // strong reference to keep parent alive
private readonly System.Data.IsolationLevel _isolationLevel;
private WeakReference _nestedTransaction; // child transactions
private WrappedTransaction _transaction;
internal OleDbConnection _parentConnection;
private static int _objectTypeCount; // Bid counter
internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
private sealed class WrappedTransaction : WrappedIUnknown {
private bool _mustComplete;
internal WrappedTransaction(UnsafeNativeMethods.ITransactionLocal transaction, int isolevel, out OleDbHResult hr) : base(transaction) {
int transactionLevel = 0;
Bid.Trace("\n");
RuntimeHelpers.PrepareConstrainedRegions();
try { } finally {
hr = transaction.StartTransaction(isolevel, 0, IntPtr.Zero, out transactionLevel);
if (0 <= hr) {
_mustComplete = true;
}
}
Bid.Trace(" %08X{HRESULT}\n", hr);
}
internal bool MustComplete {
get { return _mustComplete; }
}
internal OleDbHResult Abort() {
Debug.Assert(_mustComplete, "transaction already completed");
OleDbHResult hr;
bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
DangerousAddRef(ref mustRelease);
Bid.Trace(" handle=%p\n", base.handle);
RuntimeHelpers.PrepareConstrainedRegions();
try { } finally {
hr = (OleDbHResult)NativeOledbWrapper.ITransactionAbort(DangerousGetHandle());
_mustComplete = false;
}
Bid.Trace(" %08X{HRESULT}\n", hr);
}
finally {
if (mustRelease) {
DangerousRelease();
}
}
return hr;
}
internal OleDbHResult Commit() {
Debug.Assert(_mustComplete, "transaction already completed");
OleDbHResult hr;
bool mustRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
DangerousAddRef(ref mustRelease);
Bid.Trace(" handle=%p\n", base.handle);
RuntimeHelpers.PrepareConstrainedRegions();
try { } finally {
hr = (OleDbHResult)NativeOledbWrapper.ITransactionCommit(DangerousGetHandle());
if ((0 <= (int)hr) || (OleDbHResult.XACT_E_NOTRANSACTION == hr)) {
_mustComplete = false;
}
}
Bid.Trace(" %08X{HRESULT}\n", hr);
}
finally {
if (mustRelease) {
DangerousRelease();
}
}
return hr;
}
override protected bool ReleaseHandle() {
if (_mustComplete && (IntPtr.Zero != base.handle)) {
Bid.Trace(" handle=%p\n", base.handle);
OleDbHResult hr = (OleDbHResult)NativeOledbWrapper.ITransactionAbort(base.handle);
_mustComplete = false;
Bid.Trace(" %08X{HRESULT}\n", hr);
}
return base.ReleaseHandle();
}
}
internal OleDbTransaction(OleDbConnection connection, OleDbTransaction transaction, IsolationLevel isolevel) {
OleDbConnection.VerifyExecutePermission();
_parentConnection = connection;
_parentTransaction = transaction;
switch(isolevel) {
case IsolationLevel.Unspecified: // OLE DB doesn't support this isolevel on local transactions
isolevel = IsolationLevel.ReadCommitted;
break;
case IsolationLevel.Chaos:
case IsolationLevel.ReadUncommitted:
case IsolationLevel.ReadCommitted:
case IsolationLevel.RepeatableRead:
case IsolationLevel.Serializable:
case IsolationLevel.Snapshot:
break;
default:
throw ADP.InvalidIsolationLevel(isolevel); // MDAC 74269
}
_isolationLevel = isolevel;
}
new public OleDbConnection Connection { // MDAC 66655
get {
return _parentConnection;
}
}
override protected DbConnection DbConnection {
get {
return Connection;
}
}
override public IsolationLevel IsolationLevel {
get {
if (null == _transaction) {
throw ADP.TransactionZombied(this);
}
return _isolationLevel;
}
}
internal int ObjectID {
get {
return _objectID;
}
}
internal OleDbTransaction Parent {
get {
return _parentTransaction;
}
}
public OleDbTransaction Begin(IsolationLevel isolevel) {
OleDbConnection.ExecutePermission.Demand(); // MDAC 81476
IntPtr hscp;
Bid.ScopeEnter(out hscp, " %d#, isolevel=%d{IsolationLevel}", ObjectID, (int)isolevel);
try {
if (null == _transaction) {
throw ADP.TransactionZombied(this);
}
else if ((null != _nestedTransaction) && _nestedTransaction.IsAlive) {
throw ADP.ParallelTransactionsNotSupported(Connection);
}
// either the connection will be open or this will be a zombie
OleDbTransaction transaction = new OleDbTransaction(_parentConnection, this, isolevel);
_nestedTransaction = new WeakReference(transaction, false);
UnsafeNativeMethods.ITransactionLocal wrapper = null;
try {
wrapper = (UnsafeNativeMethods.ITransactionLocal)_transaction.ComWrapper();
transaction.BeginInternal(wrapper);
}
finally {
if (null != wrapper) {
Marshal.ReleaseComObject(wrapper);
}
}
return transaction;
}
finally {
Bid.ScopeLeave(ref hscp);
}
}
public OleDbTransaction Begin() {
return Begin(IsolationLevel.ReadCommitted);
}
internal void BeginInternal(UnsafeNativeMethods.ITransactionLocal transaction) {
OleDbHResult hr;
_transaction = new WrappedTransaction(transaction, (int) _isolationLevel, out hr);
if (hr < 0) {
_transaction.Dispose();
_transaction = null;
ProcessResults(hr);
}
}
override public void Commit() {
OleDbConnection.ExecutePermission.Demand(); // MDAC 81476
IntPtr hscp;
Bid.ScopeEnter(out hscp, " %d#", ObjectID);
try {
if (null == _transaction) {
throw ADP.TransactionZombied(this);
}
CommitInternal();
}
finally {
Bid.ScopeLeave(ref hscp);
}
}
private void CommitInternal() {
if (null == _transaction) {
return;
}
if (null != _nestedTransaction) {
OleDbTransaction transaction = (OleDbTransaction) _nestedTransaction.Target;
if ((null != transaction) && _nestedTransaction.IsAlive) {
transaction.CommitInternal();
}
_nestedTransaction = null;
}
OleDbHResult hr = _transaction.Commit();
if (!_transaction.MustComplete) {
_transaction.Dispose();
_transaction = null;
DisposeManaged();
}
if (hr < 0) {
// if an exception is thrown, user can try to commit their transaction again
ProcessResults(hr);
}
}
/*public OleDbCommand CreateCommand() { // MDAC 68309
OleDbCommand cmd = Connection.CreateCommand();
cmd.Transaction = this;
return cmd;
}
IDbCommand IDbTransaction.CreateCommand() {
return CreateCommand();
}*/
protected override void Dispose(bool disposing) {
if (disposing) {
DisposeManaged();
RollbackInternal(false);
}
base.Dispose(disposing);
}
private void DisposeManaged() {
if (null != _parentTransaction) {
_parentTransaction._nestedTransaction = null;
//_parentTransaction = null;
}
else if (null != _parentConnection) { // MDAC 67287
_parentConnection.LocalTransaction = null;
}
_parentConnection = null;
}
private void ProcessResults(OleDbHResult hr) {
Exception e = OleDbConnection.ProcessResults(hr, _parentConnection, this);
if (null != e) { throw e; }
}
override public void Rollback() {
IntPtr hscp;
Bid.ScopeEnter(out hscp, " %d#", ObjectID);
try {
if (null == _transaction) {
throw ADP.TransactionZombied(this);
}
DisposeManaged();
RollbackInternal(true); // no recover if this throws an exception
}
finally {
Bid.ScopeLeave(ref hscp);
}
}
/*protected virtual*/internal OleDbHResult RollbackInternal(bool exceptionHandling) {
OleDbHResult hr = 0;
if (null != _transaction) {
if (null != _nestedTransaction) {
OleDbTransaction transaction = (OleDbTransaction) _nestedTransaction.Target;
if ((null != transaction) && _nestedTransaction.IsAlive) {
hr = transaction.RollbackInternal(exceptionHandling);
if (exceptionHandling && (hr < 0)) {
SafeNativeMethods.Wrapper.ClearErrorInfo();
return hr;
}
}
_nestedTransaction = null;
}
hr = _transaction.Abort();
_transaction.Dispose();
_transaction = null;
if (hr < 0) {
if (exceptionHandling) {
ProcessResults(hr);
}
else {
SafeNativeMethods.Wrapper.ClearErrorInfo();
}
}
}
return hr;
}
static internal OleDbTransaction TransactionLast(OleDbTransaction head) {
if (null != head._nestedTransaction) {
OleDbTransaction current = (OleDbTransaction) head._nestedTransaction.Target;
if ((null != current) && head._nestedTransaction.IsAlive) {
return TransactionLast(current);
}
}
return head;
}
static internal OleDbTransaction TransactionUpdate(OleDbTransaction transaction) {
if ((null != transaction) && (null == transaction._transaction)) {
return null;
}
return transaction;
}
}
}
// 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
- ProfileServiceManager.cs
- MasterPageCodeDomTreeGenerator.cs
- ClickablePoint.cs
- DeviceContext2.cs
- CountAggregationOperator.cs
- TextRunCacheImp.cs
- NameValuePermission.cs
- VariableBinder.cs
- BuildProviderCollection.cs
- Binding.cs
- XmlFormatExtensionPointAttribute.cs
- BulletedListEventArgs.cs
- DataColumnMapping.cs
- Gdiplus.cs
- WebBrowserHelper.cs
- ContainerControl.cs
- ErrorTableItemStyle.cs
- Pens.cs
- InstanceContextManager.cs
- BindingGroup.cs
- Cursor.cs
- PreProcessInputEventArgs.cs
- LexicalChunk.cs
- PrintPreviewControl.cs
- HtmlShim.cs
- PkcsMisc.cs
- EventLogPermissionEntry.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- BoolExpr.cs
- BasicBrowserDialog.cs
- EFTableProvider.cs
- EventData.cs
- KeyboardEventArgs.cs
- CodeTypeMemberCollection.cs
- ServiceDeploymentInfo.cs
- TiffBitmapEncoder.cs
- PanelStyle.cs
- MULTI_QI.cs
- WindowsSlider.cs
- ServiceObjectContainer.cs
- InvalidCastException.cs
- ISAPIWorkerRequest.cs
- ListParagraph.cs
- ToolstripProfessionalRenderer.cs
- RemotingConfigParser.cs
- DataGridCell.cs
- SevenBitStream.cs
- ButtonChrome.cs
- FontStretches.cs
- Identifier.cs
- TextEffect.cs
- DateTimeUtil.cs
- TranslateTransform3D.cs
- ToolStripItemClickedEventArgs.cs
- HtmlInputFile.cs
- MetabaseSettingsIis7.cs
- RegionIterator.cs
- Pen.cs
- TextWriter.cs
- RuntimeEnvironment.cs
- XmlDictionaryReader.cs
- EnumUnknown.cs
- CodeTypeMember.cs
- MemoryFailPoint.cs
- PropagatorResult.cs
- ObfuscateAssemblyAttribute.cs
- ExternalFile.cs
- ValueUnavailableException.cs
- OpenFileDialog.cs
- LingerOption.cs
- GlyphTypeface.cs
- ObjectContextServiceProvider.cs
- TypefaceMap.cs
- EventDescriptorCollection.cs
- SafeProcessHandle.cs
- Point4D.cs
- CompilationLock.cs
- MinimizableAttributeTypeConverter.cs
- CardSpacePolicyElement.cs
- ServicePointManager.cs
- XmlILAnnotation.cs
- TcpProcessProtocolHandler.cs
- EventItfInfo.cs
- CqlLexerHelpers.cs
- GridViewDeletedEventArgs.cs
- Encoder.cs
- TaskFormBase.cs
- EditorPartChrome.cs
- OdbcErrorCollection.cs
- FixedHighlight.cs
- PolyLineSegmentFigureLogic.cs
- XmlNamedNodeMap.cs
- UITypeEditor.cs
- NameSpaceExtractor.cs
- CallContext.cs
- WebResourceUtil.cs
- ClientScriptItemCollection.cs
- NameValueFileSectionHandler.cs
- HandlerMappingMemo.cs
- Int64Converter.cs