/********************************************************************** * 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); } }
// Only for participants internal void doCommit(int txID, string coordURL) { _myCoordinatorDecision = TransactionDecision.COMMIT; Replica.updateSucessor(TX.WRITTENOBJECTS); // writePermanentLog(); endTimer(); }
// TODO: should run a separate thread to receive replies // only the coordinator should call this internal void prepare() { lock (_participantURLs) { Console.WriteLine("I'm the coordinator: " + MY_URL); if (_participantURLs.Count > 0) { foreach (String url in _participantURLs.Keys) { // TODO: A thread per participant // after all thread are sent, create one main thread responsible // for receiving votes (yes or no) - Assync callback (ver exemplo da aula 4) // and another one to run the timer Console.WriteLine("URL: " + url); IParticipant participant = (IParticipant)Activator.GetObject(typeof(IParticipant), url); //participant.canCommit(TX.TXID, MY_URL); // Create delegate to remote method RemoteAsyncDelegate RemoteDel = new RemoteAsyncDelegate(participant.canCommit); // Call delegate to remote method IAsyncResult RemAr = RemoteDel.BeginInvoke(TX.TXID, MY_URL, null, null); // Wait for the end of the call and then explictly call EndInvoke //RemAr.AsyncWaitHandle.WaitOne(); //Console.WriteLine(RemoteDel.EndInvoke(RemAr)); } timer(10000); MY_DECISION = waitParticipantsResponse(); evaluateMyDecision(); } else { // Coordinator decision // Default commit MY_DECISION = TransactionDecision.COMMIT; Console.WriteLine("AFTER MY_DECISION is commit and there are no participants"); // Send an update to the replica if there is one Replica.updateSucessor(TX.WRITTENOBJECTS); } // First phase of commit, temporary write to disk //writeAheadLog(); // if (MY_DECISION.Equals(TransactionDecision.COMMIT)) //writePermanentLog(); } }
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); }