Ejemplo n.º 1
0
        // Static function that obtains the propagation cookie to be given to the SQL Server to which
        // the connection is made to, so that the server will enlist the connection in the
        // distributed transaction.  Function returns bool indicating whether the cookie was obtained.
        public static bool GetTransactionCookie(byte[] dtcAddr, ITransaction transaction,
                                                ref UnsafeNativeMethods.ITransactionExport transactionExport,
                                                ref byte[] cookie, ref int length)
        {
            bool fSuccess = true;

            Debug.Assert(dtcAddr != null, "GetTransactionCookie: dtcAddr null!");
            Debug.Assert(transaction != null, "GetTransactionCookie: transaction null!");

            // local UInt32 variables, since the interfaces expect the UInt32 type
            UInt32 cookieLength = 0;
            UInt32 dtcLength    = (UInt32)dtcAddr.Length;

            // if the user's transactionExport is null, create one for them!
            if (null == transactionExport)
            {
                // if creation fails, return false so connection will re-obtain DTC and retry
                if (!CreateTransactionExport(dtcAddr, dtcLength, transaction,
                                             ref transactionExport))
                {
                    fSuccess = false;
                }
            }

            if (fSuccess)
            {
                // obtain the cookie length
                transactionExport.Export(transaction, ref cookieLength);

                // If export call failed, kill the instance of transactionExport and return false!
                // Checked with ShaiwalS, and this is the correct behavior.
                if (0 == cookieLength)
                {
                    transactionExport = null;
                    fSuccess          = false;
                }
                else
                {
                    // allocate the cookie to be the appropriate length
                    cookie = new byte[(int)cookieLength];

                    // obtain the cookie
                    transactionExport.GetTransactionCookie(transaction, cookieLength, cookie, ref cookieLength);

                    // set the passed in length - before we were using local UInt32
                    length = (int)cookieLength;

                    //if (AdapterSwitches.SqlPooling.TraceVerbose) {
                    //    Debug.WriteLine("Transaction.GetTransactionCookie(): cookieLength: " + cookieLength.ToString());
                    //    Debug.WriteLine("Transaction.GetTransactionCookie(): cookie: ");
                    //    for (int i=0; i<cookieLength; i++)
                    //        Debug.Write((cookie[i]).ToString("x2") + " ");

                    //    Debug.WriteLine("");
                    //}
                }
            }

            return(fSuccess);
        }
Ejemplo n.º 2
0
        private void EnlistNonNullDistributedTransaction(ITransaction transaction)
        {
            //if (AdapterSwitches.SqlPooling.TraceVerbose)
            //    Debug.WriteLine("SqlInternalConnection.EnlistDistributedTransaction(): Enlisting connection in distributed transaction...");

            if (null == _dtcAddress)
            {
                _dtcAddress = _parser.GetDTCAddress(_connectionOptions.ConnectTimeout);
            }

            Debug.Assert(_dtcAddress != null, "SqlInternalConnection.EnlistDistributedTransaction(): dtcAddress null, error #1");

            byte[] cookie = null;
            int    length = 0;

            UnsafeNativeMethods.ITransactionExport transactionExport = null;

            if (null != _transactionExport)
            {
                transactionExport = _transactionExport.GetITransactionExport();
            }

            // if the call for the cookie fails, re-obtain the DTCAddress and recall the function
            if (!Transaction.GetTransactionCookie(_dtcAddress, transaction,
                                                  ref transactionExport, ref cookie,
                                                  ref length))
            {
                _dtcAddress = _parser.GetDTCAddress(_connectionOptions.ConnectTimeout);

                Debug.Assert(_dtcAddress != null, "SqlInternalConnection.Activate(): dtcAddress null, error #2");

                if (!Transaction.GetTransactionCookie(_dtcAddress, transaction,
                                                      ref transactionExport, ref cookie,
                                                      ref length))
                {
                    throw SQL.TransactionEnlistmentError();
                }
            }

            if (null != transactionExport)
            {
                _transactionExport = new TransactionExportWrapper(transactionExport);
            }
            else
            {
                _transactionExport = null;
            }

            // send cookie to server to finish enlistment
            _parser.PropagateDistributedTransaction(cookie, length, _connectionOptions.ConnectTimeout);
        }
Ejemplo n.º 3
0
        // Private method that creates a TransactionExport for the passed in DTCAddr.
        private static bool CreateTransactionExport(byte[] dtcAddr, UInt32 dtcLength,
                                                    ITransaction transaction,
                                                    ref UnsafeNativeMethods.ITransactionExport transactionExport)
        {
            object transactionExportFactory = null;

            // UNDONE - when not using pooling - the below cast to IGetDispenser call seems to fail
            // on the 3rd pooling object.  Investigate when time permits.

            // cast to IGetDispenser, then call GetDispenser to obtain an
            // ITtransactionExportFactory interface
            ((UnsafeNativeMethods.IGetDispenser)transaction).GetDispenser(s_transactionExportFactoryGuid,
                                                                          ref transactionExportFactory);

            // cast to ITransactionExportFactory, then make call to create a ITransactionExport
            ((UnsafeNativeMethods.ITransactionExportFactory)transactionExportFactory).Create(dtcLength, dtcAddr,
                                                                                             ref transactionExport);

            // if the create call failed, then transactionExport is null and return false!
            return(null != transactionExport);
        }
Ejemplo n.º 4
0
 internal UnsafeNativeMethods.ITransactionExport GetITransactionExport()
 {
     UnsafeNativeMethods.ITransactionExport value = (UnsafeNativeMethods.ITransactionExport)System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(this.iunknown);
     GC.KeepAlive(this);
     return(value);
 }
Ejemplo n.º 5
0
 internal TransactionExportWrapper(UnsafeNativeMethods.ITransactionExport transactionExport)
 {
     this.iunknown = Marshal.GetIUnknownForObject(transactionExport);
 }