Esempio n. 1
0
        /*
        ** Name: TxResourceAsyncThreadProcessRequest
        **
        ** Description:
        **	Perform the prepare-to-commit, commit, or
        **	rollback on the database.
        **
        ** History:
        **	01-Oct-03 (thoda04)
        **	    Created.
        */
        /// <summary>
        /// Perform the prepare-to-commit, commit, or rollback on the database.
        /// </summary>
        void TxResourceAsyncThreadProcessRequest(MSDTCRequest request)
        {
            uint hr=S_OK;

            switch(request)
            {
                case MSDTCRequest.ENLIST:
                    try
                    {
                        trace.write(4, title + ":    MSDTCRequest.Enlisting with RM...");
                        if (debugging)
                            Console.WriteLine(title + ":    MSDTCRequest.Enlisting with RM...");
                        TxResourceAsync = (ITransactionResourceAsync) this;
                        XaHelperSinglePipe_EnlistWithRM(
                            RMCookie,
                            Transaction,      // pass on the incoming ITransaction
                            TxResourceAsync,  // implements ITransactionResourceAsync
                            out TxEnlistmentAsync);
                                              // receive ITransactionEnlistmentAsync

                        TxState = TXSTATE.TX_ENLISTED;

                        trace.write(4, title + ":    MSDTCRequest.Enlisted with RM successfully");
                        if (debugging)
                            Console.WriteLine(title + ":    MSDTCRequest.Enlisted with RM");
                    }
                    catch (Exception ex)
                    {
                        EnlistmentException = ex;
                        string s = ex.ToString();  // debugging
                        // release and clear the RMCookie
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                        break;
                    }

                    break;

                case MSDTCRequest.DELIST:
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.DELIST...");
                    // make sure the RMCookie is released and cleared
                    XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    break;

                case MSDTCRequest.PREPARE:
                {
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.PREPARE...");

                    hr = PrepareTx();  /* call Ingres to prepare-to-commit */
                    if (hr==S_OK)      /* transaction is prepared */
                    {
                        TxState = TXSTATE.TX_PREPARED;
                    }
                    else
                    {
                        RollbackTx(); /* prepare failed; abort the transaction */
                        TxState = TXSTATE.TX_INVALID_STATE;
                    }
                    try
                    {
                        TxEnlistmentAsync.PrepareRequestDone(
                            hr, IntPtr.Zero, IntPtr.Zero);
                        trace.write(3, title +
                            ":    TxEnlistmentAsync.PrepareRequestDone(0X" +
                            hr.ToString("X8") + ")");
                        if (debugging)
                            Console.WriteLine(title + ":    PrepareRequestDone called");
                        /* if hr==S_OK then MS DTC will dispatch the user application
                                    after the pITransaction->commit();
                         else hr==E_FAIL then DTC will
                                    pITransactionResourceAsync->Release()
                         */
                        if (TxState != TXSTATE.TX_PREPARED)
                        {
                            XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                        }
                    }
                    catch (COMException ex)
                    {
                        string s = ex.ToString();
                        trace.write(3, title + ": MSDTCRequest.PREPARE catches COMException. Message=" +
                            "\"" + ex.Message +"\"");
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
            //						throw;
                    }
                    catch (Exception ex)
                    {
                        string s = ex.ToString();
                        trace.write(3, title + ": MSDTCRequest.PREPARE catches Exception. Message=" +
                            "\"" + ex.Message + "\"");
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
            //						throw;
                    }
                    break;
                }

                case MSDTCRequest.PREPARE_E_FAIL:
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.PREPARE_E_FAIL...");
                    TxEnlistmentAsync.PrepareRequestDone(
                        E_FAIL, IntPtr.Zero, IntPtr.Zero);
                    trace.write(3, title +
                        ": TxEnlistmentAsync.PrepareRequestDone(E_FAIL)");
                    XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    break;

                case MSDTCRequest.PREPARE_E_UNEXPECTED:
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.PREPARE_E_UNEXPECTED...");
                    TxEnlistmentAsync.PrepareRequestDone(
                        E_UNEXPECTED, IntPtr.Zero, IntPtr.Zero);
                    trace.write(3, title +
                        ": TxEnlistmentAsync.PrepareRequestDone(E_FAIL)");
                    XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    break;

                case MSDTCRequest.PREPARE_SINGLE_PHASE:
                {
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.PREPARE_SINGLE_PHASE...");

                    hr = CommitTx(TMONEPHASE);          /* single phase commit optimization */
                    if (hr == S_OK)
                    {
                        hr=XACT_S_SINGLEPHASE;
                        TxState = TXSTATE.TX_ENLISTED;
                    }
                    else
                        TxState = TXSTATE.TX_INVALID_STATE;

                    try
                    {
                        TxEnlistmentAsync.PrepareRequestDone(
                            hr, IntPtr.Zero, IntPtr.Zero);
                        trace.write(4, title +
                            ": TxEnlistmentAsync.PrepareRequestDone(0X" +
                            hr.ToString("X8") + ")");
                        if (debugging)
                            Console.WriteLine(title + ":       PrepareRequestDone called");
                        if (hr == XACT_S_SINGLEPHASE)
                        {
                            if (debugging)
                                Console.WriteLine(title + ":       MSDTCRequest.PREPARE_SINGLE_PHASE releasing RMCookie...");
                            XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                        }

                    }
                    catch (Exception ex)
                    {
                        string s = ex.ToString();
                        trace.write(3, title + ": MSDTCRequest.PREPARE_SINGLE_PHASE catches Exception. Message=" +
                            "\"" + ex.Message + "\"");
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
            //						throw;
                    }
                    break;
                }

                case MSDTCRequest.COMMIT:
                {
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.COMMIT...");

                    hr = CommitTx();
                    if (hr == S_OK)
                        TxState = TXSTATE.TX_ENLISTED;
                    else
                        TxState = TXSTATE.TX_INVALID_STATE;

                    try
                    {
                        TxEnlistmentAsync.CommitRequestDone(hr);
                        trace.write(3, title +
                            ": TxEnlistmentAsync.CommitRequestDone(0X" +
                            hr.ToString("X8") + ")");
                        if (debugging)
                            Console.WriteLine(title + ":       CommitRequestDone called... Releasing RMCookie...");
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    }
                    catch (Exception ex)
                    {
                        string s = ex.ToString();  // for debugging; and ign ex
                        trace.write(3, title + ": MSDTCRequest.COMMIT catches Exception. Message=" +
                            "\"" + ex.Message + "\"");
                    }
                    break;
                }

                case MSDTCRequest.ABORT:
                {
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.ABORT...");

                    hr = RollbackTx();
                    TxState = TXSTATE.TX_ABORTED;

                    try
                    {
                        TxEnlistmentAsync.AbortRequestDone(hr);
                        trace.write(3, title +
                            ": TxEnlistmentAsync.AbortRequestDone(0X" +
                            hr.ToString("X8") + ")");
                        if (debugging)
                            Console.WriteLine(title + ":       AbortRequestDone called... Releasing RMCookie...");
                        XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    }
                    catch (Exception ex)
                    {
                        string s = ex.ToString();  // for debugging; and ign ex
                        trace.write(3, title + ": MSDTCRequest.ABORT catches Exception. Message=" +
                            "\"" + ex.Message + "\"");
                    }
                    break;
                }

                case MSDTCRequest.TMDOWN:
                {
                    if (debugging)
                        Console.WriteLine(title + ":    MSDTCRequest.TMDOWN...");

                    RollbackTx();
                    TxState = TXSTATE.TX_TMDOWN;
                    XaHelperSinglePipe_ReleaseRMCookie(ref this.RMCookie);
                    break;
                }

                default:
                    break;
            } /* end switch */
        }
Esempio n. 2
0
        /*
        ** Name: StartMSDTCRequest
        **
        ** Description:
        **	Start the TxResourceAsync thread that will asynchronously
        **	perform the transaction work.
        **	Called by one of our implentations under MSDTC Proxy thread.
        **		PrepareRequest()   start prepare-to-commit
        **		CommitRequest()    start commit
        **		AbortRequest()     start rollback
        **		TMDown()           notification that Transaction Monitor is down
        **
        ** History:
        **	01-Oct-03 (thoda04)
        **	    Created.
        */
        /// <summary>
        /// Start a MSDTC request on a worker thread.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>True if request was successfully queued.</returns>
        bool StartMSDTCRequest(MSDTCRequest request)
        {
            lock(MSDTCRequestQueue)
            {
                // first time start the worker thread
                if (txResourceAsyncThread == null  ||
                    txResourceAsyncThread.IsAlive == false)
                {
                    // only start the thread if doing the ENLIST
                    // (which should be the first call).
                    if (request != MSDTCRequest.ENLIST)
                        return false;  // should not happen, but bulletproof it

                    // fire up the thread
                    ThreadStart start =
                        new ThreadStart(TxResourceAsyncThreadMethod);
                    txResourceAsyncThread = new Thread(start);
                    //Set ApartmentState to STA to minimize
                    //any COM object creation issues.
                    txResourceAsyncThread.TrySetApartmentState(ApartmentState.STA);
                    txResourceAsyncThread.Start();
                }

                // put the request on the dispatch queue
                MSDTCRequestQueue.Enqueue(request);

                // wait for TxResourceAsync thread to start and give it
                // a chance to lock DBC connection before MSDTC Proxy might
                // return async control back to application which might try to
                // fire off another provider call before COMMIT has a
                // chance to finish.

                Monitor.Pulse(MSDTCRequestQueue);
                Monitor.Wait(MSDTCRequestQueue);
            }  // end lock

            return true;  // indicate request was successfully queued
        }