1 24 package org.objectweb.jalisto.se.impl.lock; 25 26 import org.objectweb.jalisto.se.impl.LogicalOid; 27 import org.objectweb.jalisto.se.api.internal.DataWrapper; 28 import org.objectweb.jalisto.se.exception.TransactionException; 29 import org.objectweb.jalisto.se.exception.multi.LockException; 30 import org.objectweb.jalisto.se.exception.multi.SleepingException; 31 32 import java.util.ArrayList ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 36 public class LockManagerOptimistic extends LockManagerDefault { 37 38 public void prepareCreateObject(LogicalOid floid, DataWrapper objectToCreate) { 39 Lock lock = takeLock(floid, WRITE); 40 lock.addTransactionnalValue(sessionId, objectToCreate, ObjectTransactionnalState.CREATE_ACTION, (short) 0); 41 } 42 43 public void prepareReadObjectByOid(LogicalOid floid) { 44 takeLock(floid, READ); 45 } 46 47 public void prepareDeleteObjectByOid(LogicalOid floid, short update) { 48 takeLock(floid, WRITE).addTransactionnalValue(sessionId, null, ObjectTransactionnalState.DELETE_ACTION, update); 49 } 50 51 public void finishMakeNewFileOid(LogicalOid floid) { 52 lockTable.getLockOrCreate(floid). 53 addTransactionnalValue(sessionId, null, ObjectTransactionnalState.NEW_OID_ACTION, (short) 0); 54 } 55 56 public void finishCreateObject(LogicalOid floid, DataWrapper objectToCreate) { 57 lockTable.getLock(floid).releaseWriteLock(sessionId); 58 } 59 60 public void finishReadObjectByOid(LogicalOid floid, DataWrapper objectToRead, short update) { 61 Lock lock = lockTable.getLock(floid); 62 lock.addTransactionnalValue(sessionId, objectToRead, ObjectTransactionnalState.READ_ACTION, update); 63 lock.releaseReadLock(sessionId); 64 } 65 66 public void finishUpdateObjectByOid(LogicalOid floid, DataWrapper objectToUpdate, short update) { 67 Lock lock = takeLock(floid, WRITE); 68 lock.addTransactionnalValue(sessionId, objectToUpdate, ObjectTransactionnalState.UPDATE_ACTION, update); 69 lock.releaseWriteLock(sessionId); 70 } 71 72 public void finishDeleteObjectByOid(LogicalOid floid) { 73 lockTable.getLock(floid).releaseWriteLock(sessionId); 74 } 75 76 public void commit() { 77 commitRollback(true); 78 } 79 80 public void rollback() { 81 commitRollback(false); 82 } 83 84 public void commitRollback(boolean isCommit) { 85 try { 86 accessController.getAccessControl(AccessController.COMMIT_ROLLBACK_LOCKMANAGER); 87 ArrayList usefullLocks = new ArrayList (); 88 ArrayList usefullFloids = new ArrayList (); 89 while (!getUsedLock(usefullFloids, usefullLocks)) { 90 session.sleep(usefullFloids.get(0), "during rollback"); 91 } if (isCommit) { 93 checkUpdates(usefullLocks, usefullFloids); 94 internalCommit(usefullLocks, usefullFloids); 95 } else { 96 internalRollback(usefullLocks, usefullFloids); 97 } 98 } finally { 99 accessController.releaseAccessControl(AccessController.COMMIT_ROLLBACK_LOCKMANAGER); 100 } 101 } 102 103 private void internalCommit(List usefullLocks, List usefullFloids) { 104 for (int i = 0; i < usefullLocks.size(); i++) { 105 Lock lock = (Lock) usefullLocks.get(i); 106 LogicalOid floid = (LogicalOid) usefullFloids.get(i); 107 if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.UPDATE_ACTION) { 108 lock.update(sessionId); 109 session.updateObjectCommit(floid); 110 session.getOidTable().setUpdate(sessionId, floid, lock.getUpdate(sessionId)); 111 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.CREATE_ACTION) { 112 lock.update(sessionId); 113 session.createObjectCommit(floid); 114 session.getOidTable().setUpdate(sessionId, floid, lock.getUpdate(sessionId)); 115 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.DELETE_ACTION) { 116 lock.update(sessionId); 117 session.deleteObjectCommit(floid); 118 session.getOidTable().setUpdate(sessionId, floid, lock.getUpdate(sessionId)); 119 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.NEW_OID_ACTION) { 120 session.makeNewFileOidCommit(floid); 121 } 122 lock.releaseAllLock(sessionId); 123 lockTable.removeLockByFloid(floid); 124 } 125 session.getOidTable().commit(sessionId); 126 session.getFileAccess().commit(sessionId); 127 } 128 129 private void internalRollback(List usefullLocks, List usefullFloids) { 130 for (int i = 0; i < usefullLocks.size(); i++) { 131 Lock lock = (Lock) usefullLocks.get(i); 132 synchronized (lock) { 133 LogicalOid floid = (LogicalOid) usefullFloids.get(i); 134 if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.CREATE_ACTION) { 135 session.createObjectRollback(floid); 136 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.UPDATE_ACTION) { 137 session.updateObjectRollback(floid); 138 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.DELETE_ACTION) { 139 session.deleteObjectRollback(floid); 140 } else if (lock.getCurrentAction(sessionId) == ObjectTransactionnalState.NEW_OID_ACTION) { 141 session.makeNewFileOidRollback(floid); 142 } 143 lock.releaseAllLock(sessionId); 144 lockTable.removeLockByFloid(floid); 145 } 146 } 147 session.getOidTable().rollback(sessionId); 148 session.getFileAccess().rollback(sessionId); 149 } 150 151 private boolean getUsedLock(List floidList, List lockList) { 153 floidList.clear(); 154 lockList.clear(); 155 boolean hasException = false; 156 synchronized (lockTable) { 157 Iterator lockedFloids = lockTable.getKeys(); 158 while (lockedFloids.hasNext()) { 159 LogicalOid floid = (LogicalOid) lockedFloids.next(); 160 Lock lock = lockTable.getLock(floid); 161 if (lock.hasModifiedValueWith(sessionId)) { 162 try { 163 if (lock.mustTakeWriteLock(sessionId)) { 164 lock.takeWriteLock(sessionId); 165 } 166 lockList.add(lock); 167 floidList.add(floid); 168 } catch (SleepingException fse) { 169 hasException = true; 170 session.goToBed(); 171 try { 172 lock.addSleepingSession(sessionId); 173 } catch (LockException dle) { 174 } finally { 175 floidList.clear(); 176 lockList.clear(); 177 floidList.add(floid); 178 } 179 } 180 } 181 } 182 } 183 return (!hasException); 184 } 185 186 private void checkUpdates(List locksToCheck, List floidsToCheck) { 187 for (int i = 0; i < locksToCheck.size(); i++) { 188 Lock lock = (Lock) locksToCheck.get(i); 189 int currentAction = lock.getCurrentAction(sessionId); 190 if ((currentAction == ObjectTransactionnalState.CREATE_ACTION) || 191 (currentAction == ObjectTransactionnalState.UPDATE_ACTION) || 192 (currentAction == ObjectTransactionnalState.DELETE_ACTION)) { 193 checkUpdate((LogicalOid) floidsToCheck.get(i), lock.getUpdate(sessionId)); 194 } 196 } 197 } 198 199 private void checkUpdate(LogicalOid floid, short currentUpdate) { 200 short update = session.getOidTable().getUpdate(sessionId, floid, true); 201 if ((update == 0) && (currentUpdate == 1)) { 202 return; 203 } 204 if (currentUpdate != update) { 205 TransactionException jalistoTransaction = new TransactionException("object have been modified or deleted since you get it"); 206 jalistoTransaction.setOptimistic(); 207 throw jalistoTransaction; 208 } 209 } 210 } 211 | Popular Tags |