예제 #1
0
        internal OletxTransactionManager(
            string nodeName
            )
        {
            lock ( ClassSyncObject )
            {
                // If we have not already initialized the shim factory and started the notification
                // thread, do so now.
                if (null == OletxTransactionManager.proxyShimFactory)
                {
                    Int32 error = NativeMethods.GetNotificationFactory(
                        OletxTransactionManager.ShimWaitHandle.SafeWaitHandle,
                        out OletxTransactionManager.proxyShimFactory
                        );

                    if (0 != error)
                    {
                        throw TransactionException.Create(SR.GetString(SR.TraceSourceOletx), SR.GetString(SR.UnableToGetNotificationShimFactory), null);
                    }

                    ThreadPool.UnsafeRegisterWaitForSingleObject(
                        OletxTransactionManager.ShimWaitHandle,
                        new WaitOrTimerCallback(OletxTransactionManager.ShimNotificationCallback),
                        null,
                        -1,
                        false
                        );
                }
            }

            this.dtcTransactionManagerLock = new ReaderWriterLock();

            this.nodeNameField = nodeName;

            // The DTC proxy doesn't like an empty string for node name on 64-bit platforms when
            // running as WOW64.  It treats any non-null node name as a "remote" node and turns off
            // the WOW64 bit, causing problems when reading the registry.  So if we got on empty
            // string for the node name, just treat it as null.
            if ((null != this.nodeNameField) && (0 == this.nodeNameField.Length))
            {
                this.nodeNameField = null;
            }

            if (DiagnosticTrace.Verbose)
            {
                DistributedTransactionManagerCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                                                      this.GetType(),
                                                                      this.nodeNameField
                                                                      );
            }

            // Initialize the properties from config.
            configuredTransactionOptions.IsolationLevel = isolationLevelProperty = TransactionManager.DefaultIsolationLevel;
            configuredTransactionOptions.Timeout        = timeoutProperty = TransactionManager.DefaultTimeout;

            this.internalResourceManager = new OletxInternalResourceManager(this);

            dtcTransactionManagerLock.AcquireWriterLock(-1);
            try
            {
                this.dtcTransactionManager = new DtcTransactionManager(this.nodeNameField, this);
            }
            finally
            {
                dtcTransactionManagerLock.ReleaseWriterLock();
            }

            if (resourceManagerHashTable == null)
            {
                resourceManagerHashTable     = new Hashtable(2);
                resourceManagerHashTableLock = new System.Threading.ReaderWriterLock();
            }
        }
예제 #2
0
        internal OletxCommittableTransaction CreateTransaction(
            TransactionOptions properties
            )
        {
            OletxCommittableTransaction tx = null;
            RealOletxTransaction        realTransaction = null;
            ITransactionShim            transactionShim = null;
            Guid txIdentifier = Guid.Empty;
            OutcomeEnlistment outcomeEnlistment = null;

            // Demand the distributed transation permission to create one of
            // these.
            DistributedTransactionPermission txPerm =
                new DistributedTransactionPermission(PermissionState.Unrestricted);

            txPerm.Demand();

            TransactionManager.ValidateIsolationLevel(properties.IsolationLevel);

            // Never create a transaction with an IsolationLevel of Unspecified.
            if (IsolationLevel.Unspecified == properties.IsolationLevel)
            {
                properties.IsolationLevel = configuredTransactionOptions.IsolationLevel;
            }

            properties.Timeout = TransactionManager.ValidateTimeout(properties.Timeout);

            this.dtcTransactionManagerLock.AcquireReaderLock(-1);
            try
            {
                //
                OletxTransactionIsolationLevel oletxIsoLevel = OletxTransactionManager.ConvertIsolationLevel(properties.IsolationLevel);
                UInt32 oletxTimeout = DtcTransactionManager.AdjustTimeout(properties.Timeout);

                outcomeEnlistment = new OutcomeEnlistment();
                IntPtr outcomeEnlistmentHandle = IntPtr.Zero;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    outcomeEnlistmentHandle = HandleTable.AllocHandle(outcomeEnlistment);

                    dtcTransactionManager.ProxyShimFactory.BeginTransaction(
                        oletxTimeout,
                        oletxIsoLevel,
                        outcomeEnlistmentHandle,
                        out txIdentifier,
                        out transactionShim
                        );
                }
                catch (COMException ex)
                {
                    OletxTransactionManager.ProxyException(ex);
                    throw;
                }
                finally
                {
                    if (transactionShim == null && outcomeEnlistmentHandle != IntPtr.Zero)
                    {
                        HandleTable.FreeHandle(outcomeEnlistmentHandle);
                    }
                }

                realTransaction = new RealOletxTransaction(
                    this,
                    transactionShim,
                    outcomeEnlistment,
                    txIdentifier,
                    oletxIsoLevel,
                    true
                    );
                tx = new OletxCommittableTransaction(realTransaction);
                if (DiagnosticTrace.Information)
                {
                    TransactionCreatedTraceRecord.Trace(SR.GetString(SR.TraceSourceOletx),
                                                        tx.TransactionTraceId
                                                        );
                }
            }
            finally
            {
                this.dtcTransactionManagerLock.ReleaseReaderLock();
            }

            return(tx);
        }
예제 #3
0
        internal OletxTransactionManager(
            string nodeName
            )
        {
            lock ( ClassSyncObject )
            {
                // If we have not already initialized the shim factory and started the notification
                // thread, do so now.
                if (null == OletxTransactionManager.proxyShimFactory )
                {
                    Int32 error = NativeMethods.GetNotificationFactory(
                        OletxTransactionManager.ShimWaitHandle.SafeWaitHandle,
                        out OletxTransactionManager.proxyShimFactory
                        );

                    if ( 0 != error )
                    {
                        throw TransactionException.Create( SR.GetString( SR.TraceSourceOletx ), SR.GetString( SR.UnableToGetNotificationShimFactory ), null );
                    }

                        ThreadPool.UnsafeRegisterWaitForSingleObject(
                            OletxTransactionManager.ShimWaitHandle,
                            new WaitOrTimerCallback( OletxTransactionManager.ShimNotificationCallback ),
                            null,
                            -1,
                            false
                            );
                }
            }
            
            this.dtcTransactionManagerLock = new ReaderWriterLock();

            this.nodeNameField = nodeName;

            // The DTC proxy doesn't like an empty string for node name on 64-bit platforms when
            // running as WOW64.  It treats any non-null node name as a "remote" node and turns off
            // the WOW64 bit, causing problems when reading the registry.  So if we got on empty
            // string for the node name, just treat it as null.
            if (( null != this.nodeNameField ) && ( 0 == this.nodeNameField.Length ))
            {
                this.nodeNameField = null;
            }

            if ( DiagnosticTrace.Verbose )
            {
                DistributedTransactionManagerCreatedTraceRecord.Trace( SR.GetString( SR.TraceSourceOletx ),
                    this.GetType(),
                    this.nodeNameField
                    );
            }

            // Initialize the properties from config.
            configuredTransactionOptions.IsolationLevel = isolationLevelProperty = TransactionManager.DefaultIsolationLevel;
            configuredTransactionOptions.Timeout = timeoutProperty = TransactionManager.DefaultTimeout;

            this.internalResourceManager = new OletxInternalResourceManager( this );

            dtcTransactionManagerLock.AcquireWriterLock( -1 );
            try
            {
                this.dtcTransactionManager = new DtcTransactionManager( this.nodeNameField, this );
            }
            finally
            {
                dtcTransactionManagerLock.ReleaseWriterLock();
            }
            
            if (resourceManagerHashTable == null)
            {
                resourceManagerHashTable = new Hashtable(2);
                resourceManagerHashTableLock = new System.Threading.ReaderWriterLock();
            }

        }