1515
1616public abstract class AbstractRMHashMapManager {
1717 private String m_name = "" ;
18- protected RMHashMap globalState ;
18+ protected RMHashMap globalState = new RMHashMap () ;
1919 protected HashMap <Integer , RMHashMap > transactionStates = new HashMap <>();
2020 protected XMLPersistor xmlPersistor = new XMLPersistor ();
2121 protected final String filename1 , filename2 , pointerFile , logFile ;
@@ -25,7 +25,6 @@ public abstract class AbstractRMHashMapManager {
2525
2626 private CrashMode crashMode = CrashMode .NO_CRASH ;
2727
28- // TODO: give lock to correct transaction on wakeup from failure
2928 public AbstractRMHashMapManager (String p_name , String filename1 , String filename2 , String pointerFile , String logFile ,
3029 IMiddlewareResourceManager middlewareRM ) {
3130 this .m_name = p_name ;
@@ -34,14 +33,38 @@ public AbstractRMHashMapManager(String p_name, String filename1, String filename
3433 this .pointerFile = pointerFile ;
3534 this .logFile = logFile ;
3635 this .middlewareRM = middlewareRM ;
37-
36+ this .currentCommitFile = filename2 ;
37+ }
38+
39+ public void recover () {
3840 currentCommitFile = xmlPersistor .readObject (pointerFile );
3941 if (currentCommitFile == null ) {
40- currentCommitFile = filename1 ;
42+ currentCommitFile = filename2 ; // first commit should be to other file, filename1
4143 globalState = new RMHashMap ();
4244 } else {
4345 globalState = xmlPersistor .readObject (currentCommitFile );
4446 }
47+
48+ Integer transactionVotedYes = xmlPersistor .readObject (logFile );
49+ if (transactionVotedYes != null && transactionVotedYes != -1 ) {
50+ int xid = transactionVotedYes ;
51+ String workingFile = currentCommitFile .equals (filename1 )? filename2 : filename1 ;
52+ transactionStates .put (xid , xmlPersistor .readObject (workingFile ));
53+ globalLock .lock (xid );
54+ try {
55+ if (middlewareRM .commited (xid )) {
56+ System .out .println ("middleware says to commit recovered transaction so committing" );
57+ doCommit (xid );
58+ } else {
59+ System .out .println ("middleware doesn't know about transaction so aborting" );
60+ abort (xid );
61+ }
62+ } catch (Exception e ) {
63+ System .out .println ("Failed to complete recovery on doCommit/abort " +xid );
64+ }
65+ } else {
66+ System .out .println ("did not record voting yes" );
67+ }
4568 }
4669
4770 public void crashResourceManager (CrashMode cm ) {
@@ -63,6 +86,7 @@ private void crashIf(CrashMode cm) {
6386
6487 public void vote (int xid ) throws RemoteException {
6588 System .out .println (getName () + " got vote request." );
89+ xmlPersistor .writeObject (-1 , logFile );
6690
6791 // do this all in a new thread since we want vote() to return immediately in the TM
6892 new Thread (() -> {
@@ -99,6 +123,7 @@ public void vote(int xid) throws RemoteException {
99123 updateThenPersistGlobalState (xid );
100124
101125 // TODO log YES
126+ xmlPersistor .writeObject (xid , logFile );
102127 crashIf (CrashMode .RM_AFTER_DECIDING_VOTE );
103128
104129 // uncertainty phase. Send Yes, and wait for decision
@@ -107,6 +132,7 @@ public void vote(int xid) throws RemoteException {
107132 System .out .println (GREEN .colorString ("Voting yes." ));
108133 try {
109134 middlewareRM .receiveVote (xid , true , this .m_name );
135+ xmlPersistor .writeObject (xid , logFile );
110136 crashIf (CrashMode .RM_AFTER_VOTING );
111137 return ;
112138 } catch (InvalidTransactionException ite ) {
@@ -121,6 +147,7 @@ public void vote(int xid) throws RemoteException {
121147 try {
122148 System .out .println (GREEN .colorString ("Try again to vote yes." ));
123149 middlewareRM .receiveVote (xid , true , this .m_name );
150+ xmlPersistor .writeObject (xid , logFile );
124151 crashIf (CrashMode .RM_AFTER_VOTING );
125152 return ;
126153 } catch (InvalidTransactionException ite ) {
@@ -154,6 +181,8 @@ public boolean doCommit(int xid) throws RemoteException {
154181 currentCommitFile = filename1 ;
155182 }
156183
184+ xmlPersistor .writeObject (-1 , logFile );
185+
157186 // destroy transaction-specific state
158187 removeTransactionState (xid );
159188
@@ -166,6 +195,7 @@ public boolean doCommit(int xid) throws RemoteException {
166195
167196 public boolean abort (int xid ) throws RemoteException {
168197 new Thread (() -> {
198+ xmlPersistor .writeObject (-1 , logFile );
169199 System .out .println (m_name + " aborting" );
170200 crashIf (CrashMode .RM_AFTER_RECEIVING_DECISION );
171201 if (globalLock .getLockOwner () == xid ) {
@@ -229,7 +259,10 @@ public void updateThenPersistGlobalState(int xid) {
229259 }
230260 }
231261
232- public RMItem readData (int xid , String key ) {
262+ public RMItem readData (int xid , String key ) throws UnsupportedOperationException {
263+ if (globalLock .getLockOwner () == xid )
264+ throw new UnsupportedOperationException ();
265+
233266 RMHashMap m_data = getTransactionState (xid );
234267 if (m_data == null ) {
235268 synchronized (globalState ) {
@@ -249,7 +282,10 @@ public RMItem readData(int xid, String key) {
249282 }
250283
251284 // Writes a data item
252- public void writeData (int xid , String key , RMItem value ) {
285+ public void writeData (int xid , String key , RMItem value ) throws UnsupportedOperationException {
286+ if (globalLock .getLockOwner () == xid )
287+ throw new UnsupportedOperationException ();
288+
253289 RMHashMap m_data = getTransactionState (xid );
254290 if (m_data == null ) {
255291 synchronized (globalState ) {
@@ -272,7 +308,10 @@ public void removeData(int xid, String key) {
272308 }
273309 }
274310
275- public boolean deleteItem (int xid , String key ) {
311+ public boolean deleteItem (int xid , String key ) throws UnsupportedOperationException {
312+ if (globalLock .getLockOwner () == xid )
313+ throw new UnsupportedOperationException ();
314+
276315 Trace .info ("RM::deleteItem(" + xid + ", " + key + ") called" );
277316 ReservableItem curObj = (ReservableItem ) readData (xid , key );
278317 // Check if there is such an item in the storage
@@ -292,7 +331,7 @@ public boolean deleteItem(int xid, String key) {
292331 }
293332
294333 // Query the number of available seats/rooms/cars
295- public int queryNum (int xid , String key ) {
334+ public int queryNum (int xid , String key ) throws UnsupportedOperationException {
296335 Trace .info ("RM::queryNum(" + xid + ", " + key + ") called" );
297336 ReservableItem curObj = (ReservableItem ) readData (xid , key );
298337 int value = 0 ;
@@ -304,7 +343,7 @@ public int queryNum(int xid, String key) {
304343 }
305344
306345 // Query the price of an item
307- public int queryPrice (int xid , String key ) {
346+ public int queryPrice (int xid , String key ) throws UnsupportedOperationException {
308347 Trace .info ("RM::queryPrice(" + xid + ", " + key + ") called" );
309348 ReservableItem curObj = (ReservableItem ) readData (xid , key );
310349 int value = 0 ;
0 commit comments