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 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); } } } }