KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jalisto > se > impl > lock > LockManagerOptimistic


1 /*
2  * Jalisto - JAva LIght STOrage
3  * Copyright (C) 2000-2005 Xcalia http://www.xcalia.com
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18  *
19  * Xcalia
20  * 71, rue Desnouettes
21  * 75014 Paris - France
22  * http://www.xcalia.com
23  */

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 JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
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 JavaDoc usefullLocks = new ArrayList JavaDoc();
88             ArrayList JavaDoc usefullFloids = new ArrayList JavaDoc();
89             while (!getUsedLock(usefullFloids, usefullLocks)) {
90                 session.sleep(usefullFloids.get(0), "during rollback");
91             } // we have all needed lock...
92
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 JavaDoc usefullLocks, List JavaDoc 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 JavaDoc usefullLocks, List JavaDoc 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     // floidList, lockList must be empty
152
private boolean getUsedLock(List JavaDoc floidList, List JavaDoc lockList) {
153         floidList.clear();
154         lockList.clear();
155         boolean hasException = false;
156         synchronized (lockTable) {
157             Iterator JavaDoc 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 JavaDoc locksToCheck, List JavaDoc 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 // lock.update(sessionId);
195
}
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