1 21 package com.db4o; 22 23 import com.db4o.foundation.*; 24 import com.db4o.inside.ix.IndexTransaction; 25 import com.db4o.inside.marshall.ObjectHeader; 26 import com.db4o.reflect.Reflector; 27 28 31 public abstract class Transaction { 32 33 protected int i_address; 35 protected final byte[] _pointerBuffer = new byte[YapConst.POINTER_LENGTH]; 36 37 public Tree i_delete; 40 private List4 i_dirtyFieldIndexes; 41 42 public final YapFile i_file; 43 44 final Transaction i_parentTransaction; 45 46 protected final YapWriter i_pointerIo; 47 48 private final YapStream i_stream; 49 50 private List4 i_transactionListeners; 51 52 protected Tree i_writtenUpdateDeletedMembers; 53 54 private final Collection4 _participants = new Collection4(); 56 57 public Transaction(YapStream a_stream, Transaction a_parent) { 58 i_stream = a_stream; 59 i_file = (a_stream instanceof YapFile) ? (YapFile) a_stream : null; 60 i_parentTransaction = a_parent; 61 i_pointerIo = new YapWriter(this, YapConst.POINTER_LENGTH); 62 } 63 64 public void addDirtyFieldIndex(IndexTransaction a_xft) { 65 i_dirtyFieldIndexes = new List4(i_dirtyFieldIndexes, a_xft); 66 } 67 68 public final void checkSynchronization() { 69 if(Debug.checkSychronization){ 70 stream().i_lock.notify(); 71 } 72 } 73 74 public void addTransactionListener(TransactionListener a_listener) { 75 i_transactionListeners = new List4(i_transactionListeners, a_listener); 76 } 77 78 protected void clearAll() { 79 i_dirtyFieldIndexes = null; 80 i_transactionListeners = null; 81 disposeParticipants(); 82 _participants.clear(); 83 } 84 85 private void disposeParticipants() { 86 Iterator4 iterator = _participants.iterator(); 87 while (iterator.moveNext()) { 88 ((TransactionParticipant)iterator.current()).dispose(this); 89 } 90 } 91 92 public void close(boolean a_rollbackOnClose) { 93 try { 94 if (stream() != null) { 95 checkSynchronization(); 96 stream().releaseSemaphores(this); 97 } 98 } catch (Exception e) { 99 if (Debug.atHome) { 100 e.printStackTrace(); 101 } 102 } 103 if (a_rollbackOnClose) { 104 try { 105 rollback(); 106 } catch (Exception e) { 107 if (Debug.atHome) { 108 e.printStackTrace(); 109 } 110 } 111 } 112 } 113 114 public void commit() { 115 synchronized (stream().i_lock) { 116 i_file.freeSpaceBeginCommit(); 117 commitExceptForFreespace(); 118 i_file.freeSpaceEndCommit(); 119 } 120 } 121 122 private void commitExceptForFreespace(){ 123 124 if(DTrace.enabled){ 125 boolean systemTrans = (i_parentTransaction == null); 126 DTrace.TRANS_COMMIT.logInfo( "server == " + stream().isServer() + ", systemtrans == " + systemTrans); 127 } 128 129 commit2Listeners(); 130 131 commit3Stream(); 132 133 commit4FieldIndexes(); 134 135 commit5Participants(); 136 137 stream().writeDirty(); 138 139 commit6WriteChanges(); 140 141 freeOnCommit(); 142 143 commit7ClearAll(); 144 } 145 146 protected void freeOnCommit() { 147 } 148 149 protected void commit6WriteChanges() { 150 } 151 152 private void commit7ClearAll(){ 153 commit7ParentClearAll(); 154 clearAll(); 155 } 156 157 private void commit7ParentClearAll() { 158 if(i_parentTransaction != null){ 159 i_parentTransaction.commit7ClearAll(); 160 } 161 } 162 163 private void commit2Listeners(){ 164 commit2ParentListeners(); 165 commitTransactionListeners(); 166 } 167 168 private void commit2ParentListeners() { 169 if (i_parentTransaction != null) { 170 i_parentTransaction.commit2Listeners(); 171 } 172 } 173 174 private void commit3Stream(){ 175 stream().checkNeededUpdates(); 176 stream().writeDirty(); 177 stream().classCollection().write(stream().getSystemTransaction()); 178 } 179 180 private void commit4FieldIndexes(){ 181 if(i_parentTransaction != null){ 182 i_parentTransaction.commit4FieldIndexes(); 183 } 184 if (i_dirtyFieldIndexes != null) { 185 Iterator4 i = new Iterator4Impl(i_dirtyFieldIndexes); 186 while (i.moveNext()) { 187 ((IndexTransaction) i.current()).commit(); 188 } 189 } 190 } 191 192 private void commit5Participants() { 193 if (i_parentTransaction != null) { 194 i_parentTransaction.commit5Participants(); 195 } 196 197 Iterator4 iterator = _participants.iterator(); 198 while (iterator.moveNext()) { 199 ((TransactionParticipant)iterator.current()).commit(this); 200 } 201 } 202 203 protected void commitTransactionListeners() { 204 checkSynchronization(); 205 if (i_transactionListeners != null) { 206 Iterator4 i = new Iterator4Impl(i_transactionListeners); 207 while (i.moveNext()) { 208 ((TransactionListener) i.current()).preCommit(); 209 } 210 i_transactionListeners = null; 211 } 212 } 213 214 public abstract boolean isDeleted(int id); 215 216 public boolean delete(YapObject ref, int id, int cascade) { 217 checkSynchronization(); 218 219 if(ref != null){ 220 if(! i_stream.flagForDelete(ref)){ 221 return false; 222 } 223 } 224 225 if(isDeleted(id)){ 226 return false; 227 } 228 229 if(DTrace.enabled){ 230 DTrace.TRANS_DELETE.log(id); 231 } 232 233 DeleteInfo info = (DeleteInfo) TreeInt.find(i_delete, id); 234 if(info == null){ 235 info = new DeleteInfo(id, ref, cascade); 236 i_delete = Tree.add(i_delete, info); 237 return true; 238 } 239 info._reference = ref; 240 if(cascade > info._cascade){ 241 info._cascade = cascade; 242 } 243 return true; 244 } 245 246 public void dontDelete(int a_id) { 247 if(DTrace.enabled){ 248 DTrace.TRANS_DONT_DELETE.log(a_id); 249 } 250 if(i_delete == null){ 251 return; 252 } 253 i_delete = TreeInt.removeLike((TreeInt)i_delete, a_id); 254 } 255 256 void dontRemoveFromClassIndex(int a_yapClassID, int a_id) { 257 checkSynchronization(); 260 YapClass yapClass = stream().getYapClass(a_yapClassID); 261 yapClass.index().add(this, a_id); 262 } 263 264 public Object [] objectAndYapObjectBySignature(final long a_uuid, final byte[] a_signature) { 265 checkSynchronization(); 266 return stream().getFieldUUID().objectAndYapObjectBySignature(this, a_uuid, a_signature); 267 } 268 269 public void processDeletes() { 270 if (i_delete == null) { 271 i_writtenUpdateDeletedMembers = null; 272 return; 273 } 274 275 while(i_delete != null) { 276 277 Tree delete = i_delete; 278 i_delete = null; 279 280 delete.traverse(new Visitor4() { 281 public void visit(Object a_object) { 282 DeleteInfo info = (DeleteInfo)a_object; 283 Object obj = null; 284 if(info._reference != null){ 285 obj = info._reference.getObject(); 286 } 287 if(obj == null){ 288 289 291 295 Object [] arr = stream().getObjectAndYapObjectByID(Transaction.this, info._key); 296 obj = arr[0]; 297 info._reference = (YapObject)arr[1]; 298 info._reference.flagForDelete(stream().topLevelCallId()); 299 } 300 stream().delete3(Transaction.this,info._reference ,info._cascade, false); 301 } 302 }); 303 } 304 i_writtenUpdateDeletedMembers = null; 305 } 306 307 308 public Reflector reflector(){ 309 return stream().reflector(); 310 } 311 312 public void rollback() { 313 synchronized (stream().i_lock) { 314 315 rollbackParticipants(); 316 317 rollbackFieldIndexes(); 318 319 rollbackSlotChanges(); 320 321 rollBackTransactionListeners(); 322 323 clearAll(); 324 } 325 } 326 327 protected void rollbackSlotChanges() { 328 } 329 330 private void rollbackFieldIndexes() { 331 if (i_dirtyFieldIndexes != null) { 332 Iterator4 i = new Iterator4Impl(i_dirtyFieldIndexes); 333 while (i.moveNext()) { 334 ((IndexTransaction) i.current()).rollback(); 335 } 336 } 337 } 338 339 private void rollbackParticipants() { 340 Iterator4 iterator = _participants.iterator(); 341 while (iterator.moveNext()) { 342 ((TransactionParticipant)iterator.current()).rollback(this); 343 } 344 } 345 346 protected void rollBackTransactionListeners() { 347 checkSynchronization(); 348 if (i_transactionListeners != null) { 349 Iterator4 i = new Iterator4Impl(i_transactionListeners); 350 while (i.moveNext()) { 351 ((TransactionListener) i.current()).postRollback(); 352 } 353 i_transactionListeners = null; 354 } 355 } 356 357 void setAddress(int a_address) { 358 i_address = a_address; 359 } 360 361 public abstract void setPointer(int a_id, int a_address, int a_length); 362 363 void slotDelete(int a_id, int a_address, int a_length) { 364 } 365 366 public void slotFreeOnCommit(int a_id, int a_address, int a_length) { 367 } 368 369 void slotFreeOnRollback(int a_id, int a_address, int a_length) { 370 } 371 372 void slotFreeOnRollbackCommitSetPointer(int a_id, int newAddress, int newLength) { 373 } 374 375 void slotFreeOnRollbackSetPointer(int a_id, int a_address, int a_length) { 376 } 377 378 public void slotFreePointerOnCommit(int a_id) { 379 } 380 381 void slotFreePointerOnCommit(int a_id, int a_address, int a_length) { 382 } 383 384 boolean supportsVirtualFields(){ 385 return true; 386 } 387 388 public Transaction systemTransaction(){ 389 if(i_parentTransaction != null){ 390 return i_parentTransaction; 391 } 392 return this; 393 } 394 395 public String toString() { 396 return stream().toString(); 397 } 398 399 400 public void writePointer(int a_id, int a_address, int a_length) { 401 if(DTrace.enabled){ 402 DTrace.WRITE_POINTER.log(a_id); 403 DTrace.WRITE_POINTER.logLength(a_address, a_length); 404 } 405 checkSynchronization(); 406 i_pointerIo.useSlot(a_id); 407 if (Deploy.debug) { 408 i_pointerIo.writeBegin(YapConst.YAPPOINTER); 409 } 410 i_pointerIo.writeInt(a_address); 411 i_pointerIo.writeInt(a_length); 412 if (Deploy.debug) { 413 i_pointerIo.writeEnd(); 414 } 415 if (Debug.xbytes && Deploy.overwrite) { 416 i_pointerIo.setID(YapConst.IGNORE_ID); 417 } 418 i_pointerIo.write(); 419 } 420 421 422 public void writeUpdateDeleteMembers(int a_id, YapClass a_yc, int a_type, int a_cascade) { 423 checkSynchronization(); 424 if(Tree.find(i_writtenUpdateDeletedMembers, new TreeInt(a_id)) != null){ 425 return; 426 } 427 if(DTrace.enabled){ 428 DTrace.WRITE_UPDATE_DELETE_MEMBERS.log(a_id); 429 } 430 i_writtenUpdateDeletedMembers = Tree.add(i_writtenUpdateDeletedMembers, new TreeInt(a_id)); 431 YapWriter objectBytes = stream().readWriterByID(this, a_id); 432 if(objectBytes == null){ 433 if (a_yc.hasIndex()) { 434 dontRemoveFromClassIndex(a_yc.getID(), a_id); 435 } 436 return; 437 } 438 439 ObjectHeader oh = new ObjectHeader(stream(), a_yc, objectBytes); 440 441 DeleteInfo info = (DeleteInfo)TreeInt.find(i_delete, a_id); 442 if(info != null){ 443 if(info._cascade > a_cascade){ 444 a_cascade = info._cascade; 445 } 446 } 447 448 objectBytes.setCascadeDeletes(a_cascade); 449 a_yc.deleteMembers(oh._marshallerFamily, oh._headerAttributes, objectBytes, a_type, true); 450 slotFreeOnCommit(a_id, objectBytes.getAddress(), objectBytes.getLength()); 451 } 452 453 public final YapStream stream() { 454 return i_stream; 455 } 456 457 public void enlist(TransactionParticipant participant) { 458 if (null == participant) { 459 throw new ArgumentNullException("participant"); 460 } 461 checkSynchronization(); 462 if (!_participants.containsByIdentity(participant)) { 463 _participants.add(participant); 464 } 465 } 466 467 public static Transaction readInterruptedTransaction(YapFile file, YapReader reader) { 468 int transactionID1 = reader.readInt(); 469 int transactionID2 = reader.readInt(); 470 if( (transactionID1 > 0) && (transactionID1 == transactionID2)){ 471 Transaction transaction = file.newTransaction(null); 472 transaction.setAddress(transactionID1); 473 return transaction; 474 } 475 return null; 476 } 477 478 public Transaction parentTransaction() { 479 return i_parentTransaction; 480 } 481 482 }
| Popular Tags
|