public boolean enlist(int xid, ResourceManager rm) throws RemoteException { if (enlistList.containsKey(xid)) { Set<ResourceManager> set = enlistList.get(xid); Iterator<ResourceManager> i = set.iterator(); ResourceManager r = null; while (i.hasNext()) { try { r = i.next(); r.getMyRMIName(); } catch (Exception e) { enlistList.get(xid).remove(r); System.out.println("A hole in enlist."); } } enlistList.get(xid).add(rm); protocolDB.get(xid).put(rm.getMyRMIName(), rm.getStatus(xid)); } else { Set<ResourceManager> set = new HashSet<ResourceManager>(); set.add(rm); enlistList.put(xid, set); HashMap<String, TwoPC_ST> map = new HashMap<String, TwoPC_ST>(); map.put(rm.getMyRMIName(), TwoPC_ST.Initiated); protocolDB.put(xid, map); } return true; }
public void abortOtherRMsExcept(String rmName, int xid) throws RemoteException, InvalidTransactionException { Set<ResourceManager> set = enlistList.get(xid); Iterator<ResourceManager> i = set.iterator(); ResourceManager r = null; while (i.hasNext()) { r = i.next(); if (r.getMyRMIName().equals(rmName)) { enlistList.get(xid).remove(r); break; } } abort(xid); }
public void sendVote(ResourceManager rm, int xid, TwoPC_ST result) throws RemoteException { protocolDB.get(xid).put(rm.getMyRMIName(), result); }
public static void main(String args[]) throws RemoteException, InvalidTransactionException, TransactionAbortedException { System.setSecurityManager(new RMISecurityManager()); String rmiPort = System.getProperty("rmiPort"); if (rmiPort == null) { rmiPort = ""; } else if (!rmiPort.equals("")) { rmiPort = "//:" + rmiPort + "/"; } try { TransactionManagerImpl obj = new TransactionManagerImpl(); Naming.rebind(rmiPort + TransactionManager.RMIName, obj); System.out.println("TM bound"); } catch (Exception e) { System.err.println("TM not bound:" + e); System.exit(1); } enlistList = new HashMap<Integer, Set<ResourceManager>>(); File f = new File(enlistFile); if (f.exists()) { try { ObjectInputStream fin = new ObjectInputStream(new FileInputStream(f)); enlistList = (HashMap<Integer, Set<ResourceManager>>) fin.readObject(); fin.close(); } catch (Exception e) { e.printStackTrace(); } } protocolDB = new HashMap<Integer, Map<String, TwoPC_ST>>(); File f2 = new File(protocolDBFile); if (f2.exists()) { try { ObjectInputStream fin2 = new ObjectInputStream(new FileInputStream(f2)); protocolDB = (HashMap<Integer, Map<String, TwoPC_ST>>) fin2.readObject(); fin2.close(); } catch (Exception e) { e.printStackTrace(); } // recovery for (Integer i : protocolDB.keySet()) { if (i > xidCounter) { xidCounter = i + 1; } Map<String, TwoPC_ST> lastST = protocolDB.get(i); boolean re1 = true; for (TwoPC_ST st : lastST.values()) re1 &= (st == TwoPC_ST.Committed); if (re1) { protocolDB.remove(i); enlistList.remove(i); continue; } System.out.println("TM recovery xid: " + i + " from half commit."); Set<ResourceManager> commitSet = enlistList.get(i); boolean re2 = true; Set<ResourceManager> commitSet2 = new HashSet<ResourceManager>(); for (ResourceManager r : commitSet) { if (r.getStatus(i) == TwoPC_ST.Prepared) { System.out.println("TM recovery " + i + " in " + r.getMyRMIName()); commitSet2.add(r); } else if (r.getStatus(i) == TwoPC_ST.Committed) ; else re2 = false; } System.out.println("here 1"); if (re2) { for (ResourceManager r : commitSet2) { r.commit(i); } protocolDB.remove(i); enlistList.remove(i); } } } }
public boolean commit(int xid) throws RemoteException, TransactionAbortedException, InvalidTransactionException { System.out.println("TM starts to commit " + xid); if (!xidIsValid(xid)) { File f = new File(logFile); if (f.exists()) throw new TransactionAbortedException(xid, ""); else throw new InvalidTransactionException(xid, ""); } if (!enlistList.containsKey(xid)) { throw new TransactionAbortedException(xid, "Nonexist xid for TM."); } Set<ResourceManager> commitSet = enlistList.get(xid); System.out.println(xid + " TM commitSet size: " + commitSet.size()); ResourceManager rm = null; Iterator<ResourceManager> i = commitSet.iterator(); try { while (i.hasNext()) { rm = i.next(); rm.vote(xid, TwoPC_ST.Prepared); rm.getMyRMIName(); System.out.println(rm.getMyRMIName() + " in TM commit " + xid); } } catch (Exception e) { System.out.println("When vote, there is an exception"); enlistList.get(xid).remove(rm); abort(xid); throw new TransactionAbortedException(xid, "invalid rm"); } if (dieTMBeforeCommit) dieNow(); // log "committed" here, and enlistList try { File logF = new File(logFile); FileWriter fw = new FileWriter(logF.getAbsoluteFile(), true); bw = new BufferedWriter(fw); bw.write(Integer.toString(xid)); bw.write(" committed\n"); bw.close(); ObjectOutputStream protocolDBBackup = new ObjectOutputStream(new FileOutputStream(protocolDBFile)); protocolDBBackup.writeObject(protocolDB); protocolDBBackup.close(); ObjectOutputStream enlistFileBackup = new ObjectOutputStream(new FileOutputStream(enlistFile)); enlistFileBackup.writeObject(enlistList); enlistFileBackup.close(); } catch (IOException e) { e.printStackTrace(); } if (dieTMAfterCommit) dieNow(); for (ResourceManager r : commitSet) { r.commit(xid); } protocolDB.remove(xid); enlistList.remove(xid); try { ObjectOutputStream protocolDBBackup = new ObjectOutputStream(new FileOutputStream(protocolDBFile)); protocolDBBackup.writeObject(protocolDB); protocolDBBackup.close(); // enlistFile ObjectOutputStream enlistFileBackup = new ObjectOutputStream(new FileOutputStream(enlistFile)); enlistFileBackup.writeObject(enlistList); enlistFileBackup.close(); } catch (IOException e) { e.printStackTrace(); } return true; }