예제 #1
0
        /**********************************************************************
        * 2PC protocol section
        * TODO: Maybe it could be in another section (like a different class)
        **********************************************************************/

        /**********************************************************************
        * COORDINATOR part
        **********************************************************************/

        // This method is only called by the coordinator
        // URLs is the list of participants of transaction txID
        internal static bool Commit(int txID, List <String> URLs)
        {
            try
            {
                Console.WriteLine("Datastore.Commit: Commit do Datastore");
                TentativeTx tx = _tentativeTransactions[txID];
                tx.COORDINATOR = new CoordinatorManager(tx, URLs);
                tx.COORDINATOR.prepare();
                if (tx.COORDINATOR.MY_DECISION.Equals(TransactionDecision.ABORT))
                {
                    return(false);
                }

                addValues(tx.WRITTENOBJECTS);

                // Send an update to the replica if there is one
                if (Replica.updateSucessor(tx.WRITTENOBJECTS).Equals(UpdateState.COMMIT))
                {
                    return(true);
                }

                return(false);
            }
            catch (Exception)
            {
                Console.WriteLine("CATCH IN COMMIT");
                return(false);
            }
        }
예제 #2
0
        /**
         * createTentativeTx
         * @param txID the transaction id
         * @param clientURL the url of the client where this transaction is being executed
         *
         * creates a tentative transaction in the datastore server
         **/
        internal static TentativeTx createTentativeTx(int txID, string clientURL)
        {
            TentativeTx tx = new TentativeTx(txID, clientURL);

            _tentativeTransactions.Add(txID, tx);
            return(tx);
        }
예제 #3
0
        private static List <ServerObject> getVersionsByUID(int uid, int txID)
        {
            TentativeTx         tx             = _tentativeTransactions[txID];
            bool                versionWritten = false;
            List <ServerObject> versions       = new List <ServerObject>();

            foreach (ServerObject obj in tx.WRITTENOBJECTS)
            {
                if (obj.UID == uid)
                {
                    versions.Add(obj);
                    versionWritten = true;
                }
            }
            if (versionWritten)
            {
                return(versions);
            }
            lock (_serverObjects)
            {
                foreach (ServerObject obj in _serverObjects)
                {
                    if (obj.UID == uid)
                    {
                        versions.Add(obj);
                    }
                }
            }
            return(versions);
        }
예제 #4
0
        /***********************************************************************
        * PARTICIPANT part
        ***********************************************************************/

        /**
         * canCommit
         * @param txID id of the transaction to commit
         * @coordURL url of the coordinator server in the protocol
         *
         * this method is called from coordinator to participants to commit their values
         * and reply to the coordinator with an answer of success
         **/
        internal static void canCommit(int txID, string coordURL)
        {
            TentativeTx tx = _tentativeTransactions[txID];

            tx.PARTICIPANT = new ParticipantManager(tx);
            tx.PARTICIPANT.COORDINATORURL = coordURL;
            tx.PARTICIPANT.canCommit();
        }
예제 #5
0
 internal ParticipantManager(TentativeTx tx)
 {
     MY_URL               = Datastore.SERVERURL + "Participant";
     TX                   = tx;
     MY_DECISION          = TransactionDecision.DEFAULT;
     COORDINATOR_DECISION = TransactionDecision.DEFAULT;
     //createLogDirectory();
 }
예제 #6
0
 internal CoordinatorManager(TentativeTx tx, List <String> URLs)
 {
     TIMER       = null;
     MY_URL      = Datastore.SERVERURL + "Coordinator";
     TX          = tx;
     MY_DECISION = TransactionDecision.DEFAULT;
     initializeParticipants(URLs);
     // createLogDirectory();
 }
예제 #7
0
        /**
         * Registers a tentative READ
         * @return VOID
         *
         * TODO: the method needs rework to make it efficient
         **/
        internal static int regTentativeRead(int uid, int txID, string clientURL)
        {
            try
            {
                if (!_tentativeTransactions.ContainsKey(txID))
                {
                    createTentativeTx(txID, clientURL);
                }

                TentativeTx tx = _tentativeTransactions[txID];

                // We must ensure there's always a version for txID to read
                List <ServerObject> versions = getVersionsRead(tx.WRITTENOBJECTS, uid);

                versions.Sort((x, y) => x.WRITETS.CompareTo(y.WRITETS));
                versions.Reverse();
                foreach (ServerObject obj in versions)
                {
                    if (obj.WRITETS <= txID)
                    {
                        obj.READTS = txID;
                        return(obj.VALUE);
                    }
                }

                // Only comes here if it's not in written objects of this tx
                versions = getVersionsRead(_serverObjects, uid);

                versions.Sort((x, y) => x.WRITETS.CompareTo(y.WRITETS));
                versions.Reverse();
                foreach (ServerObject obj in versions)
                {
                    if (obj.WRITETS <= txID)
                    {
                        obj.READTS = txID;
                        return(obj.VALUE);
                    }
                }
                return(-1); // It should never reach this point
            }
            catch (Exception)
            {
                Console.WriteLine("Catch CALLING WRITE!");
                return(-1);
            }
        }
예제 #8
0
        internal static void doCommit(int txID, string coordURL)
        {
            TentativeTx tx = _tentativeTransactions[txID];

            tx.PARTICIPANT.doCommit(txID, coordURL);
            // Send an update to the replica if there is one
            Console.WriteLine("MY OBJECTS ARE : ");

            //replaceValue(tx.WRITTENOBJECTS);
            addValues(tx.WRITTENOBJECTS);

            /*
             * foreach (ServerObject o in SERVEROBJECTS)
             * {
             *  Console.WriteLine("\t UID= " + o.UID + " VALUE=" + o.VALUE);
             * }
             */
            Replica.updateSucessor(tx.WRITTENOBJECTS);
        }
예제 #9
0
        /**
         * Registers a tentative Write
         * @return TRUE if the value could be written
         * @return FALSE if the write is in conflict, cascading into an abort Tx
         **/
        internal static bool regTentativeWrite(int uid, int newVal, int txID, string clientURL)
        {
            if (!_tentativeTransactions.ContainsKey(txID))
            {
                createTentativeTx(txID, clientURL);
            }

            List <ServerObject> versions = getVersionsByUID(uid, txID);
            int earlierReadTS            = versions.Max(readts => readts.READTS);

            if (earlierReadTS <= txID)
            {
                ServerObject tentativeWrite = new ServerObject(uid, newVal, txID);

                TentativeTx tx = _tentativeTransactions[txID];
                tx.AddObject(tentativeWrite);

                return(true); // proceed with transaction
            }
            else
            {
                return(false); // abort transaction
            }
        }
예제 #10
0
        internal static void doAbort(int txID, string coordURL)
        {
            TentativeTx tx = _tentativeTransactions[txID];

            tx.PARTICIPANT.doAbort(txID, coordURL);
        }
예제 #11
0
        internal static bool haveCommitted(int txID, String url)
        {
            TentativeTx tx = _tentativeTransactions[txID];

            return(tx.COORDINATOR.haveCommitted(url));
        }
예제 #12
0
        internal static void participantVoteNo(int txID, String URL)
        {
            TentativeTx tx = _tentativeTransactions[txID];

            tx.COORDINATOR.participantNo(URL);
        }