1 30 31 32 package org.hsqldb; 33 34 import org.hsqldb.lib.DoubleIntIndex; 35 import org.hsqldb.lib.HashMappedList; 36 import org.hsqldb.lib.HsqlArrayList; 37 import org.hsqldb.lib.LongKeyIntValueHashMap; 38 39 46 public class TransactionManager { 47 48 LongKeyIntValueHashMap rowSessionMap; 49 boolean reWriteProtect; 50 Database database; 51 52 TransactionManager(Database db) { 53 database = db; 54 rowSessionMap = new LongKeyIntValueHashMap(true); 55 } 56 57 public void setReWriteProtection(boolean value) { 58 reWriteProtect = value; 59 } 60 61 void checkDelete(Session session, Row row) throws HsqlException {} 62 63 void checkDelete(Session session, 64 HashMappedList rowSet) throws HsqlException { 65 66 if (!reWriteProtect) { 67 return; 68 } 69 70 int sessionid = session.getId(); 71 72 for (int i = 0, size = rowSet.size(); i < size; i++) { 73 Row row = (Row) rowSet.getKey(i); 74 long rowid = row.getId(); 75 76 if (rowSessionMap.get(rowid, sessionid) != sessionid) { 77 throw Trace.error(Trace.INVALID_TRANSACTION_STATE_NO_SUBCLASS, 78 Trace.ITSNS_OVERWRITE); 79 } 80 } 81 } 82 83 void checkDelete(Session session, 84 HsqlArrayList rowSet) throws HsqlException { 85 86 if (!reWriteProtect) { 87 return; 88 } 89 90 int sessionid = session.getId(); 91 92 for (int i = 0, size = rowSet.size(); i < size; i++) { 93 Row row = (Row) rowSet.get(i); 94 long rowid = row.getId(); 95 96 if (rowSessionMap.get(rowid, sessionid) != sessionid) { 97 throw Trace.error(Trace.INVALID_TRANSACTION_STATE_NO_SUBCLASS, 98 Trace.ITSNS_OVERWRITE); 99 } 100 } 101 } 102 103 void commit(Session session) { 104 105 Object [] list = session.rowActionList.getArray(); 106 int size = session.rowActionList.size(); 107 108 for (int i = 0; i < size; i++) { 109 Transaction tx = (Transaction) list[i]; 110 long rowid = tx.row.getId(); 111 112 tx.commit(session); 113 rowSessionMap.remove(rowid); 114 } 115 116 session.rowActionList.clear(); 117 session.savepoints.clear(); 118 } 119 120 synchronized void rollback(Session session) { 121 rollbackTransactions(session, 0, false); 122 session.savepoints.clear(); 123 } 124 125 void rollbackSavepoint(Session session, 126 String name) throws HsqlException { 127 128 int index = session.savepoints.getIndex(name); 129 130 if (index < 0) { 131 throw Trace.error(Trace.SAVEPOINT_NOT_FOUND, name); 132 } 133 134 Integer oi = (Integer ) session.savepoints.get(index); 135 int limit = oi.intValue(); 136 137 rollbackTransactions(session, limit, false); 138 139 while (session.savepoints.size() > index) { 140 session.savepoints.remove(session.savepoints.size() - 1); 141 } 142 } 143 144 void rollbackTransactions(Session session, int limit, boolean log) { 145 146 Object [] list = session.rowActionList.getArray(); 147 int size = session.rowActionList.size(); 148 149 for (int i = size - 1; i >= limit; i--) { 150 Transaction tx = (Transaction) list[i]; 151 152 tx.rollback(session, log); 153 } 154 155 for (int i = limit; i < size; i++) { 156 Transaction tx = (Transaction) list[i]; 157 long rowid = tx.row.getId(); 158 159 rowSessionMap.remove(rowid); 160 } 161 162 session.rowActionList.setSize(limit); 163 } 164 165 void addTransaction(Session session, Transaction transaction) { 166 167 if (reWriteProtect) { 168 rowSessionMap.put(transaction.row.getId(), session.getId()); 169 } 170 } 171 172 private long globalActionTimestamp = 0; 173 174 177 long nextActionTimestamp() { 178 179 globalActionTimestamp++; 180 181 return globalActionTimestamp; 182 } 183 184 187 Transaction[] getTransactionList() { 188 189 Session[] sessions = database.sessionManager.getAllSessions(); 190 int[] tIndex = new int[sessions.length]; 191 Transaction[] transactions; 192 int transactionCount = 0; 193 194 { 195 int actioncount = 0; 196 197 for (int i = 0; i < sessions.length; i++) { 198 actioncount += sessions[i].getTransactionSize(); 199 } 200 201 transactions = new Transaction[actioncount]; 202 } 203 204 while (true) { 205 boolean found = false; 206 long minChangeNo = Long.MAX_VALUE; 207 int sessionIndex = 0; 208 209 for (int i = 0; i < sessions.length; i++) { 211 int tSize = sessions[i].getTransactionSize(); 212 213 if (tIndex[i] < tSize) { 214 Transaction current = 215 (Transaction) sessions[i].rowActionList.get( 216 tIndex[i]); 217 218 if (current.SCN < minChangeNo) { 219 minChangeNo = current.SCN; 220 sessionIndex = i; 221 } 222 223 found = true; 224 } 225 } 226 227 if (!found) { 228 break; 229 } 230 231 HsqlArrayList currentList = sessions[sessionIndex].rowActionList; 232 233 for (; tIndex[sessionIndex] < currentList.size(); ) { 234 Transaction current = 235 (Transaction) currentList.get(tIndex[sessionIndex]); 236 237 if (current.SCN == minChangeNo + 1) { 239 minChangeNo++; 240 } 241 242 if (current.SCN == minChangeNo) { 243 transactions[transactionCount++] = current; 244 245 tIndex[sessionIndex]++; 246 } else { 247 break; 248 } 249 } 250 } 251 252 return transactions; 253 } 254 255 258 public DoubleIntIndex getTransactionIDList() { 259 260 Session[] sessions = database.sessionManager.getAllSessions(); 261 DoubleIntIndex lookup = new DoubleIntIndex(10, false); 262 263 lookup.setKeysSearchTarget(); 264 265 for (int i = 0; i < sessions.length; i++) { 266 HsqlArrayList tlist = sessions[i].rowActionList; 267 268 for (int j = 0, size = tlist.size(); j < size; j++) { 269 Transaction tx = (Transaction) tlist.get(j); 270 271 if (tx.tTable.getTableType() == Table.CACHED_TABLE) { 272 lookup.addUnique(tx.row.getPos(), 0); 273 } 274 } 275 } 276 277 return lookup; 278 } 279 280 283 public void convertTransactionIDs(DoubleIntIndex lookup) { 284 285 Session[] sessions = database.sessionManager.getAllSessions(); 286 287 for (int i = 0; i < sessions.length; i++) { 288 HsqlArrayList tlist = sessions[i].rowActionList; 289 290 for (int j = 0, size = tlist.size(); j < size; j++) { 291 Transaction tx = (Transaction) tlist.get(j); 292 293 if (tx.tTable.getTableType() == Table.CACHED_TABLE) { 294 int pos = lookup.lookupFirstEqual(tx.row.getPos()); 295 296 tx.row.setPos(pos); 297 } 298 } 299 } 300 } 301 } 302 | Popular Tags |