예제 #1
0
        /// <summary>
        /// Start the recovery scan for XIDs and position cursor at start of list.
        /// </summary>
        /// <param name="rm">Resource manager to start scan for.</param>
        /// <returns>Count of XIDs in whole list or XAER* error code.</returns>
        private int xa_recover_startrscan(RM rm)
        {
            const string MASTER_DB = "iidbdb";

            int rc = XA_OK;
            rm.Xids = new AdvanXID[0];  // init to empty in case bad things happen
            AdvanXID[] xids = rm.Xids;

            AdvanConnect conn;

            ConnectStringConfig config =  // make a copy
                new ConnectStringConfig(rm.Config);

            // XIDs need to come from iidbdb database
            config.Set(DrvConst.DRV_PROP_DB, MASTER_DB);

            try
            {
                conn =
                    new AdvanConnect(
                    null, rm.Host, config, trace, (AdvanXID)null);
            }
            catch (Exception ex)
            {
                trace.write("xa_recover: Exception thrown on Connection open: "+
                    ex.ToString());
                return XAER_RMFAIL;  // could not connect
            }

            try
            {
                xids = conn.getPreparedTransactionIDs(rm.DatabaseName);
            }
            catch (Exception ex)
            {
                trace.write("xa_recover: Exception thrown on GetXIDs: "+
                    ex.ToString());
                rc = XAER_RMERR;  // could not connect
            }
            finally
            {
                try
                {
                    conn.close();
                }
                catch(Exception /* ignore */) {}
            }

            if (rc != XA_OK)
                return rc;

            rm.Cursor =0;      // reset cursor to XID list back to start
            if (xids != null)  // safety check
                rm.Xids = xids;  // new list of XIDs

            return rm.Xids.Length;
        }
예제 #2
0
        /*
        ** Name: xa_open  - Open an RMI, registered earlier with the TP system.
        **
        ** Description:
        **
        ** Inputs:
        **      xa_info    - character string, contains the RMI open string.
        **      rmid       - RMI identifier, assigned by the TP system, unique to the
        **                   AS process w/which LIBQXA is linked in.
        **      flags      - TP system-specified flags, one of TMASYNC/TMNOFLAGS.
        **
        ** Outputs:
        **	Returns:
        **          XA_OK          - normal execution.
        **          XAER_ASYNC     - if TMASYNC was specified. Currently, we don't
        **                           support TMASYNC (post-Ingres65 feature).
        **          XAER_RMERR     - various internal errors.
        **          XAER_INVAL     - illegal input arguments.
        **          XAER_PROTO     - if the RMI is in the wrong state. Enforces the
        **                           state tables in the XA spec.
        **
        ** History:
        **	18-Aug-03 (thoda04)
        **	    Created.  Rich description copied from front/embed/libqxa.
        */
        /// <summary>
        /// xa_open is called by the transaction manager to initialize
        /// the resource manager.  This method is called first, before 
        /// any other xa_ methods are called.  xa_open is loaded and
        /// called at MSDTC enlistment.  It allows MSDTC to
        /// test that the connection parameters work while running under
        /// the MSDTC user identity and authorization.  If there is a
        /// problem, we want to know at enlistment time and not at
        /// a recovery situation.  MSDTC also calls xa_open
        /// when it wants to xa_recover and commit/rollback
        /// in-doubt transactions.  Unfortunately, these connections have
        /// different connection parms depending on the recover or 
        /// commit/rollback.  Therefore, we can't re-use the connection
        /// and we immediately close the connection after the successful
        /// test of the xa_open.
        /// </summary>
        /// <param name="xa_info">XA OpenString containing information to
        /// connect to the host and database.  Max length is 256 characters.</param>
        /// <param name="rmid">An integer, assigned by the transaction manager,
        /// uniquely identifies the called resource manager within the thread
        /// of control.  The TM passes this rmid on subsequent calls to XA
        /// routines to identify the RM.  This identifier remains constant
        /// until the TM in this thread closes the RM.</param>
        /// <param name="flags">TMASYNC if function to be performed async.
        /// TMNOFLAGS is no other flags are set.</param>
        /// <returns>XA_OK for normal execution or an XAER* error code.</returns>
        public int xa_open(
			[MarshalAs(UnmanagedType.LPStr)]
			string xa_info,
			int rmid,
			long flags)
        {
            int rc = XA_OK;
            int trace_level = 0;

            string sanitizedString;
            IConfig config;

            if (xa_info == null)
            {
                trace.write("xa_open: xa_info = <null>"+
                    ", rmid = " + rmid.ToString());
                return XAER_INVAL;  // invalid arguments were specified
            }

            if (xa_info.Length == 0)
            {
                trace.write("xa_open: xid = <Empty String>"+
                    ", rmid = " + rmid.ToString());
                return XAER_INVAL;  // invalid arguments were specified
            }

            try
            {
                config = ConnectStringConfig.ParseConnectionString(
                    xa_info, out sanitizedString, true);
            }
            catch (Exception)
            {
                trace.write("xa_open: xa_info = <invalid connection string>"+
                    ", rmid = " + rmid.ToString());
                return XAER_INVAL;  // invalid arguments were specified
            }

            // propagate the XA tracing from the application process
            // to this MSDTC process and send output to event log.
            string    strValue;
            // Check for XA tracing
            strValue = config.get(DrvConst.DRV_PROP_TRACE);
            if (strValue != null  &&  strValue.ToUpper(
                System.Globalization.CultureInfo.InvariantCulture)=="XA")
            {
                strValue = config.get(DrvConst.DRV_PROP_TRACELVL);
                if (strValue != null)
                {
                    try
                    {
                        trace_level = Int32.Parse(strValue);
                        if (trace_level < 0)
                            trace_level = 0;
                    }
                    catch {}
                }
            }

            if (trace_level >= 3)  // until tracing is setup, do this manually
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder(100);

                sb.Append("xa_info = ");
                sb.Append("\"");
                sb.Append(sanitizedString);

                sb.Append(", rmid = ");
                sb.Append(rmid);

                sb.Append(", flags = ");
                sb.Append(XAFlagsToString(flags));

                trace.write("xa_open: " + sb.ToString());
            }

            string host;

            host = config.get(DrvConst.DRV_PROP_HOST);
            if (host == null)  // default to local
                host = "";

            if (host == null)
            {
                trace.write("xa_open: Error: host specification missing"+
                    ", rmid = " + rmid.ToString());
                return XAER_INVAL;  // invalid connection string was specified
            }

            // if not "servername:port" format then
            // get the port number from keyword=value NameValueCollection
            if (host.IndexOf(":") == -1)
            {
                string port = config.get(DrvConst.DRV_PROP_PORT);
                if (port == null || port.Length == 0)
                    port = "II7"; // no "Port=" then default to "II7"
                host += ":" + port.ToString();  // add ":portid" to host
            }

            AdvanConnect conn;
            try
            {
                conn =
                    new AdvanConnect(null, host, config, trace, (AdvanXID) null);
            }
            catch (Exception ex)
            {
                if (trace_level >= 1) // until tracing is setup, do this manually
                trace.write("xa_open: Exception thrown on Connection open: "+
                    ex.ToString());
                return XAER_RMERR;  // could not connect
            }

            RM rm = new RM(rmid, conn, host, config, trace_level);
            lock(RMcollection)
            {
                RMcollection[rmid] = rm;

                if (trace_level > 0)  // if tracing requested, turn if on
                {
                    int old_trace_level = trace.setTraceLevel(trace_level);
                    if (old_trace_level > trace_level)  // if old > new
                        trace.setTraceLevel(old_trace_level);  // set it back
                    CountOfRMsTracing++;
                }
            }
            try
            {
                // we don't need this connection, close it.  We just needed
                // to test that it could open and get its values for later.
                // We don't want to find out that the connection string
                // is bad for the MSDTC user context at real recovery.
                conn.close();   // we don't need this connection, close it.
            }
            catch (Exception /* ignore any close errors*/)
            {}

            return rc;
        }
예제 #3
0
        /// <summary>
        /// Common code for xa_commit and xa_rollback
        /// </summary>
        /// <param name="isCommit">If commit then true, else rollback.</param>
        /// <param name="xid">XID to perform the work on.</param>
        /// <param name="rmid">An integer, assigned by the transaction manager,
        /// uniquely identifies the called resource manager within the thread
        /// of control.</param>
        /// <param name="flags"></param>
        /// <returns>XA_OK for normal execution or an XAER* error code.</returns>
        private int xa_commit_or_rollback(
			bool     isCommit,
			AdvanXID xid,
			int rmid,
			long flags)
        {
            string title = isCommit?"xa_commit":"xa_rollback";

            RM rm = FindRM(rmid);
            if (rm == null)  // if RM not found, error
                return XAER_INVAL;

            AdvanConnect conn;
            try
            {
                conn =
                    new AdvanConnect(
                        null, rm.Host, rm.Config, trace, xid);
            }
            catch (Exception ex)
            {
                trace.write(title+": Exception thrown on Connection open: "+
                    ex.ToString());
                return XAER_RMERR;  // could not connect
            }

            try
            {
                if (isCommit)
                    conn.commit();
                else
                    conn.rollback();
            }
            catch (Exception ex)
            {
                trace.write(title+": Exception thrown on "+
                    (isCommit?"commit()":"rollback()") + ": " +
                    ex.ToString());
                return XAER_RMERR;  // could not connect
            }

            try
            {
                conn.close();
            }
            catch
            {}

            return XA_OK;
        }