1 25 26 package org.objectweb.perseus.persistence.lib; 27 28 import org.objectweb.fractal.api.control.BindingController; 29 import org.objectweb.perseus.cache.api.CacheEntry; 30 import org.objectweb.perseus.cache.api.CacheException; 31 import org.objectweb.perseus.cache.api.CacheFullException; 32 import org.objectweb.perseus.cache.api.CacheManager; 33 import org.objectweb.perseus.cache.api.FixableCacheEntry; 34 import org.objectweb.perseus.cache.api.UnbindManager; 35 import org.objectweb.perseus.concurrency.api.ConcurrencyException; 36 import org.objectweb.perseus.concurrency.api.ConcurrencyManager; 37 import org.objectweb.perseus.concurrency.api.RolledBackConcurrencyException; 38 import org.objectweb.perseus.persistence.api.MemoryInstanceManager; 39 import org.objectweb.perseus.persistence.api.PersistenceException; 40 import org.objectweb.perseus.persistence.api.RolledBackPersistenceException; 41 import org.objectweb.perseus.persistence.api.State; 42 import org.objectweb.perseus.persistence.api.StateFilter; 43 import org.objectweb.perseus.persistence.api.StateManager; 44 import org.objectweb.perseus.persistence.api.StorageManager; 45 import org.objectweb.perseus.persistence.api.TransactionalPersistenceManager; 46 import org.objectweb.perseus.persistence.api.TransactionalWorkingSet; 47 import org.objectweb.perseus.persistence.api.WorkingSet; 48 import org.objectweb.perseus.persistence.api.WorkingSetLifeCycle; 49 import org.objectweb.perseus.persistence.api.WorkingSetManager; 50 import org.objectweb.perseus.persistence.api.VirtualState; 51 import org.objectweb.perseus.persistence.api.PersistentObjectLifeCycleExcpetion; 52 import org.objectweb.perseus.persistence.api.NoDSIPersistenceException; 53 import org.objectweb.perseus.persistence.concurrency.NoDSIConcurrencyException; 54 import org.objectweb.util.monolog.api.BasicLevel; 55 import org.objectweb.util.monolog.api.Logger; 56 57 import java.util.Iterator ; 58 import java.util.Set ; 59 import java.util.ArrayList ; 60 61 77 public class TransactionalPersistenceManagerImpl 78 implements TransactionalPersistenceManager, BindingController { 79 80 public final static String CACHE_MANAGER_BINDING = "cache-manager"; 81 public final static String CONCURRENCY_MANAGER_BINDING = "concurrency-manager"; 82 public final static String STORAGE_MANAGER_BINDING = "storage-manager"; 83 public final static String STATE_MANAGER_BINDING = "state-manager"; 84 public final static String MEMORY_INSTANCE_MANAGER_BINDING = "memory-instance-manager"; 85 public final static String UNBIND_MANAGER_BINDING = "unbind-manager"; 86 public final static String WORKINGSET_MANAGER_BINDING = "workingset-manager"; 87 88 91 protected CacheManager cache; 92 93 protected UnbindManager unbindManager; 94 95 98 protected ConcurrencyManager cm; 99 100 104 protected StorageManager storage; 105 106 109 protected StateManager stateManager; 110 111 114 protected WorkingSetManager wsManager; 115 116 119 protected MemoryInstanceManager mim; 120 121 protected Logger logger = null; 122 123 136 protected void bindCeInWS(State state, WorkingSet ws, byte mode) 137 throws PersistenceException { 138 Object oid = state.getCacheEntry().getCeIdentifier(); 139 ws.bind(state, oid, mode); 140 } 141 142 143 155 protected CacheEntry getCacheEntry(WorkingSet ws, 156 Object oid) throws PersistenceException { 157 CacheEntry ce = cache.lookup(oid); 158 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 159 logger.log(BasicLevel.DEBUG, "getCacheEntry( " + oid + ")"); 160 } 161 if (ce != null) { 162 return ce; 163 } 164 return createCacheEntry(ws, oid); 166 } 167 168 177 protected CacheEntry createCacheEntry(WorkingSet ws, 178 Object oid) throws PersistenceException { 179 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 180 logger.log(BasicLevel.DEBUG, "createCacheEntry( " + oid + ")"); 181 } 182 Object obj = null; 183 obj = mim.newInstance(oid, ws.getConnectionHolder()); 185 CacheEntry ce; 186 try { 188 ce = cache.bind(oid, obj); 189 stateManager.setReferenceState(ce, null); 191 } catch (CacheFullException e) { 192 throw new RolledBackPersistenceException(e); 193 } catch (CacheException e) { 194 ce = cache.lookup(oid); 197 } 198 return ce; 199 } 200 201 209 protected void checkCacheEntry(CacheEntry ce) throws PersistenceException { 210 Object oid = ce.getCeIdentifier(); 211 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 212 logger.log(BasicLevel.DEBUG, "checkCacheEntry " + oid); 213 } 214 if (((FixableCacheEntry) ce).getCeFixCount() == 0) { 215 CacheEntry _ce = cache.lookup(oid); 216 if (_ce == null) { 217 try { 219 ce = cache.bind(oid, ce.getCeObject()); 220 } catch (CacheFullException e) { 221 throw new RolledBackPersistenceException(e); 222 } catch (CacheException e) { 223 ce = cache.lookup(oid); 226 } 227 } else if (ce != _ce) { 228 throw new RolledBackPersistenceException( 230 "Another persistent object is already present into the cache (identifier=" + oid + ")"); 231 } 232 } 233 } 234 235 242 private boolean prepareWS(WorkingSet ws, boolean validate) 243 throws PersistenceException { 244 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 245 logger.log(BasicLevel.DEBUG, "prepareWS " + ws + " / " + validate); 246 } 247 boolean valid = validate; 248 PersistenceException pe = null; 249 try { 250 ws.setStatus(WorkingSetLifeCycle.getNextStatus( 251 ws.getStatus(), WorkingSetLifeCycle.PREPARE_ACTION)); 252 } catch (PersistenceException e) { 253 pe = e; 254 valid = false; 255 } 256 try { 257 valid = cm.validate(ws) && valid; 259 if (pe != null) { 260 throw pe; 261 } 262 if (valid) { 263 Set entries = ws.entries(); 265 for (Iterator it = entries.iterator(); it.hasNext();) { 266 State state = (State) it.next(); 267 if (state == VirtualState.instance) { 268 continue; 269 } 270 if (stateManager.isDirty(state)) { 271 storage.write(ws.getConnectionHolder(), 272 state.getCacheEntry().getCeIdentifier(), 273 state); 274 } 275 } 276 } 277 } catch(Exception e) { 278 valid = false; 280 throw (e instanceof PersistenceException 281 ? (PersistenceException) e 282 : new PersistenceException("An exception occurs during the " 283 + "working preparation, it is marked as rolled back",e)); 284 } finally { 285 ws.getConnectionHolder().releaseCHConnection(); 287 if (valid) { 288 ws.setStatus(WorkingSetLifeCycle.getNextStatus( 289 ws.getStatus(), WorkingSetLifeCycle.PREPARE_OK_ACTION)); 290 } else { 291 ws.setStatus(WorkingSetLifeCycle.getNextStatus( 292 ws.getStatus(), WorkingSetLifeCycle.PREPARE_FAIL_ACTION)); 293 } 294 } 295 return valid; 296 } 297 298 304 private void commitWS(WorkingSet ws, 305 byte action) throws PersistenceException { 306 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 307 logger.log(BasicLevel.DEBUG, "commitWS " + ws + " / " + action); 308 } 309 byte newStatus = WorkingSetLifeCycle.getNextStatus( 310 ws.getStatus(), action); 311 try { 312 ws.getConnectionHolder().commitCH(); 313 } catch (PersistenceException e) { 314 rollbackWS(ws, WorkingSetLifeCycle.ROLLBACK_ACTION); 315 throw new RolledBackPersistenceException(e); 316 } 317 318 try { 319 ArrayList unexportedOids = null; 320 for (Iterator it = ws.entries().iterator(); it.hasNext();) { 321 State state = (State) it.next(); 322 if (state == VirtualState.instance) { 323 continue; 324 } 325 if (stateManager.isUnexported(state)) { 326 if (unexportedOids == null) { 327 unexportedOids = new ArrayList (); 328 } 329 CacheEntry ce = state.getCacheEntry(); 331 unexportedOids.add(ce.getCeIdentifier()); 332 stateManager.makeUnbound(ce); 334 } 335 } 336 if (unexportedOids != null) { 337 unbindManager.unbindAll(unexportedOids, true); 339 } 340 } catch (CacheException e) { 341 throw new PersistenceException(e); 342 } finally { 343 try { 344 ws.getConnectionHolder().closeCHConnection(); 345 } finally { 346 cm.finalize(ws); 347 ws.setStatus(newStatus); 348 ws.clear(); 349 storage.endWS(ws); 350 } 351 } 352 } 353 354 360 private void rollbackWS(WorkingSet ws, 361 byte action) throws PersistenceException { 362 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 363 logger.log(BasicLevel.DEBUG, "rollbackWS " + ws + " / " + action); 364 } 365 byte newStatus = WorkingSetLifeCycle.getNextStatus( 366 ws.getStatus(), action); 367 try { 368 try { 369 ws.getConnectionHolder().rollbackCH(); 370 } finally { 371 ws.setStatus(newStatus); 372 } 373 ArrayList unexportedOids = null; 374 for (Iterator i = ws.entries().iterator(); i.hasNext();) { 375 State state = (State) i.next(); 376 if (state == VirtualState.instance) { 377 continue; 378 } 379 CacheEntry ce = state.getCacheEntry(); 380 if (stateManager.isExported(state)) { 381 if (unexportedOids == null) { 382 unexportedOids = new ArrayList (); 383 } 384 unexportedOids.add(ce.getCeIdentifier()); 385 stateManager.makeUnbound(ce); 386 } 387 388 } 389 if (unexportedOids != null) { 390 unbindManager.unbindAll(unexportedOids, true); 392 } 393 } catch (CacheException ce) { 394 throw new PersistenceException("Impossible to rollback - ", ce); 395 } finally { 396 try { 397 ws.getConnectionHolder().closeCHConnection(); 398 } finally { 399 cm.abort(ws); 400 ws.clear(); 401 ws.setStatus(newStatus); 402 storage.endWS(ws); 403 } 404 } 405 } 406 407 private void assertOpenWorkingset(WorkingSet ws) throws PersistenceException { 408 if (ws.getStatus() == WorkingSet.CTX_CLOSED) { 409 throw new PersistenceException("Impossible to work with a closed WorkingSet"); 410 } 411 } 412 413 416 public String [] listFc() { 417 return new String []{ 418 CACHE_MANAGER_BINDING, 419 CONCURRENCY_MANAGER_BINDING, 420 STATE_MANAGER_BINDING, 421 STORAGE_MANAGER_BINDING, 422 MEMORY_INSTANCE_MANAGER_BINDING, 423 UNBIND_MANAGER_BINDING, 424 WORKINGSET_MANAGER_BINDING, 425 STATE_MANAGER_BINDING 426 }; 427 } 428 429 public Object lookupFc(String s) { 430 if (CACHE_MANAGER_BINDING.equals(s)) { 431 return cache; 432 } else if (CONCURRENCY_MANAGER_BINDING.equals(s)) { 433 return cm; 434 } else if (STATE_MANAGER_BINDING.equals(s)) { 435 return stateManager; 436 } else if (STORAGE_MANAGER_BINDING.equals(s)) { 437 return storage; 438 } else if (MEMORY_INSTANCE_MANAGER_BINDING.equals(s)) { 439 return mim; 440 } else if (UNBIND_MANAGER_BINDING.equals(s)) { 441 return unbindManager; 442 } else if (WORKINGSET_MANAGER_BINDING.equals(s)) { 443 return wsManager; 444 } else if (STATE_MANAGER_BINDING.equals(s)) { 445 return stateManager; 446 } 447 return null; 448 } 449 450 public void bindFc(String s, Object o) { 451 if ("logger".equals(s)) { 452 logger = (Logger) o; 453 } else if (CACHE_MANAGER_BINDING.equals(s)) { 454 cache = (CacheManager) o; 455 } else if (CONCURRENCY_MANAGER_BINDING.equals(s)) { 456 cm = (ConcurrencyManager) o; 457 } else if (STATE_MANAGER_BINDING.equals(s)) { 458 stateManager = (StateManager) o; 459 } else if (STORAGE_MANAGER_BINDING.equals(s)) { 460 storage = (StorageManager) o; 461 } else if (MEMORY_INSTANCE_MANAGER_BINDING.equals(s)) { 462 mim = (MemoryInstanceManager) o; 463 } else if (UNBIND_MANAGER_BINDING.equals(s)) { 464 unbindManager = (UnbindManager) o; 465 } else if (WORKINGSET_MANAGER_BINDING.equals(s)) { 466 wsManager = (WorkingSetManager) o; 467 } else if (STATE_MANAGER_BINDING.equals(s)) { 468 stateManager = (StateManager) o; 469 } 470 } 471 472 public void unbindFc(String s) { 473 if (CACHE_MANAGER_BINDING.equals(s)) { 474 cache = null; 475 } else if (CONCURRENCY_MANAGER_BINDING.equals(s)) { 476 cm = null; 477 } else if (STATE_MANAGER_BINDING.equals(s)) { 478 stateManager = null; 479 } else if (STORAGE_MANAGER_BINDING.equals(s)) { 480 storage = null; 481 } else if (MEMORY_INSTANCE_MANAGER_BINDING.equals(s)) { 482 mim = null; 483 } else if (UNBIND_MANAGER_BINDING.equals(s)) { 484 unbindManager = null; 485 } else if (WORKINGSET_MANAGER_BINDING.equals(s)) { 486 wsManager = null; 487 } else if (STATE_MANAGER_BINDING.equals(s)) { 488 stateManager = null; 489 } 490 } 491 492 495 public State export(WorkingSet ws, Object obj) 496 throws PersistenceException { 497 return export(ws, obj, null); 498 } 499 500 public State export(WorkingSet ws, Object obj, Object hints) 501 throws PersistenceException { 502 if (logger.isLoggable(BasicLevel.DEBUG)) 503 logger.log(BasicLevel.DEBUG, "export ctx=" + ws 504 + " / obj=" + obj.getClass().getName() 505 + " / hints=" + hints); 506 assertOpenWorkingset(ws); 507 State state = null; 508 Object oid = null; 510 CacheEntry ce = null; 511 try { 512 513 if (hints == null) { 514 oid = storage.export(ws.getConnectionHolder(), obj); 515 } else { 516 oid = storage.export(ws.getConnectionHolder(), obj, hints); 517 } 518 519 ce = cache.bind(oid, obj); 521 522 state = writeIntention(ws, ce, null); 524 stateManager.makeExported(state); 525 return state; 526 } catch (PersistenceException e) { 527 if (ce != null) { 528 stateManager.makeUnbound(ce); 529 } 530 throw e; 531 } catch (CacheFullException e) { 532 throw new RolledBackPersistenceException(e); 533 } catch (CacheException e) { 534 try { 538 state = ws.lookup(oid); 539 if (state != null && stateManager.isUnexported(state)) { 540 ce = cache.lookup(oid); 541 if (ce != null) { 542 unbindManager.unbind(oid, true); 544 ce = cache.bind(oid, obj); 546 stateManager.makeBound(ce, oid); 548 ws.bind(VirtualState.instance, oid, WorkingSet.WRITE_INTENTION); 549 state = writeIntention(ws, ce, null); 551 stateManager.makeClean(state); 553 stateManager.makeDirty(state); 554 return state; 556 } 557 } 558 } catch (CacheException cacheE) { 559 throw new PersistenceException( 560 "Cannot put object into cache, oid=" + oid, cacheE); 561 } 562 throw new PersistenceException( 563 "Cannot put object into cache, oid=" + oid, e); 564 } 565 } 566 567 public State unexport(WorkingSet ws, Object oid) throws PersistenceException { 568 return unexport(ws, getCacheEntry(ws, oid)); 569 } 570 571 public State unexport(WorkingSet ws, CacheEntry ce) 572 throws PersistenceException { 573 assertOpenWorkingset(ws); 574 if (!stateManager.isBound(ce)) { 575 throw new PersistentObjectLifeCycleExcpetion( 576 PersistentObjectLifeCycleExcpetion.UNEXPORT_NPO_MSG); 577 } 578 Object oid = ce.getCeIdentifier(); 579 State state = null; 580 state = writeIntention(ws, ce, null); 582 storage.unexport(ws.getConnectionHolder(), oid, ce); 584 stateManager.makeUnexported(state); 585 return state; 586 } 587 588 public State readIntention(WorkingSet ws, Object oid, Object thinLock) 589 throws PersistenceException { 590 return readIntention(ws, getCacheEntry(ws, oid), thinLock); 591 } 592 593 public CacheEntry getObjectById(WorkingSet ws, Object oid) 594 throws PersistenceException { 595 if (logger.isLoggable(BasicLevel.DEBUG)) { 596 logger.log(BasicLevel.DEBUG, "getObjectById ctx=" + ws 597 + " / oid=" + oid); 598 } 599 assertOpenWorkingset(ws); 600 State s = ws.lookup(oid); 602 if (s != null && s != VirtualState.instance) { 603 return s.getCacheEntry(); 604 } 605 return getCacheEntry(ws, oid); 606 } 607 608 615 public State readIntention(WorkingSet ws, CacheEntry ce, Object thinLock) throws PersistenceException { 616 assertOpenWorkingset(ws); 617 if (!stateManager.isBound(ce)) { 618 throw new PersistentObjectLifeCycleExcpetion( 619 PersistentObjectLifeCycleExcpetion.READ_NPO_MSG); 620 } 621 checkCacheEntry(ce); 622 State state; 623 try { 625 state = (State) cm.readIntention(ws, ce, thinLock); 626 } catch (RolledBackConcurrencyException e) { 627 throw new RolledBackPersistenceException(e); 628 } catch (NoDSIConcurrencyException e) { 629 try { 630 unbindManager.unbind(ce.getCeIdentifier(), true); 631 } catch (CacheException e1) { 632 logger.log(BasicLevel.ERROR, 633 "Impossible to unbind from the cache an entry which " + 634 "does not exist on the data support", e1); 635 } 636 throw new NoDSIPersistenceException(e); 637 } catch (ConcurrencyException e) { 638 throw new PersistenceException(e); 639 } 640 Object oid = state.getCacheEntry().getCeIdentifier(); 641 ws.bind(state, oid, WorkingSet.READ_INTENTION); 642 return state; 643 } 644 645 public State writeIntention(WorkingSet ws, Object oid, Object thinLock) 646 throws PersistenceException { 647 return writeIntention(ws, getCacheEntry(ws, oid), thinLock); 648 } 649 650 public State writeIntention(WorkingSet ws, CacheEntry ce, Object thinLock) 651 throws PersistenceException { 652 assertOpenWorkingset(ws); 653 if (!stateManager.isBound(ce)) { 654 throw new PersistentObjectLifeCycleExcpetion( 655 PersistentObjectLifeCycleExcpetion.WRITE_NPO_MSG); 656 } 657 checkCacheEntry(ce); 658 State state; 659 try { 661 state = (State) cm.writeIntention(ws, ce, thinLock); 662 } catch (RolledBackConcurrencyException e) { 663 throw new RolledBackPersistenceException(e); 664 } catch (NoDSIConcurrencyException e) { 665 try { 666 unbindManager.unbind(ce.getCeIdentifier(), true); 667 } catch (CacheException e1) { 668 logger.log(BasicLevel.ERROR, 669 "Impossible to unbind from the cache an entry which " + 670 "does not exist on the data support", e1); 671 } 672 throw new NoDSIPersistenceException(e); 673 } catch (ConcurrencyException e) { 674 throw new PersistenceException(e); 675 } 676 Object oid = state.getCacheEntry().getCeIdentifier(); 677 ws.bind(state, oid, WorkingSet.WRITE_INTENTION); 678 stateManager.makeDirty(state); 679 return state; 680 } 681 682 689 public void accessCompletion(WorkingSet ws, State ce) throws PersistenceException { 690 assertOpenWorkingset(ws); 691 } 692 693 700 public void flush(WorkingSet ws, StateFilter statefilter) 701 throws PersistenceException { 702 assertOpenWorkingset(ws); 703 Iterator it = ws.entries().iterator(); 704 while (it.hasNext()) { 705 State state = (State) it.next(); 706 if (state == VirtualState.instance) { 707 continue; 708 } 709 if (stateManager.isDirty(state) 710 && (statefilter == null || statefilter.accept(state))) { 711 storage.write(ws.getConnectionHolder(), 712 state.getCacheEntry().getCeIdentifier(), 713 state); 714 stateManager.makeFlushed(state); 716 } 717 } 718 } 719 720 727 public void flush(WorkingSet ws, State stateToFlush) 728 throws PersistenceException { 729 assertOpenWorkingset(ws); 730 Iterator it = ws.entries().iterator(); 731 while (it.hasNext()) { 732 State state = (State) it.next(); 733 if (state == VirtualState.instance) { 734 continue; 735 } 736 if (stateManager.isDirty(state) && state == stateToFlush) { 737 storage.write(ws.getConnectionHolder(), 738 state.getCacheEntry().getCeIdentifier(), 739 state); 740 stateManager.makeFlushed(state); 742 } 743 } 744 } 745 748 public boolean evict(WorkingSet ws, Object oid, boolean force) throws PersistenceException { 749 FixableCacheEntry ce = (FixableCacheEntry) cache.lookup(oid); 750 assertOpenWorkingset(ws); 751 if (ce == null) { 752 return true; 753 } 754 int fix = ce.getCeFixCount(); 755 State state = ws.lookup(oid); 756 if (fix == 1 && state != null) { 757 if (stateManager.isDirty(state)) { 759 storage.write(ws.getConnectionHolder(), oid, state); 761 stateManager.makeFlushed(state); 762 } 763 ws.bind(VirtualState.instance, oid, WorkingSet.UNKNOWN_INTENTION); 766 } 767 if (fix > 0) { 768 if (force) { 769 throw new PersistenceException("Impossible to evict an entry from the cache: There is another user than the given working set"); 770 } else { 771 return false; 772 } 773 } 774 stateManager.setReferenceState(ce, null); 776 ce = null; 778 try { 780 return unbindManager.unbind(oid, false); 781 } catch (CacheException e) { 782 if (force) { 783 throw new PersistenceException("Impossible to unbind the entry: ", e); 784 } else { 785 return false; 786 } 787 } 788 } 789 790 public int evictAll(WorkingSet ws, boolean force) throws PersistenceException{ 791 assertOpenWorkingset(ws); 792 try { 793 return unbindManager.unbindUnfixed(force).size(); 794 } catch (CacheException e) { 795 throw new PersistenceException(e); 796 } 797 } 798 799 public void unbind(WorkingSet ws, Object oid) throws PersistenceException { 800 assertOpenWorkingset(ws); 801 unbind(ws, cache.lookup(oid)); 802 } 803 804 public void unbind(WorkingSet ws, CacheEntry ce) throws PersistenceException { 805 assertOpenWorkingset(ws); 806 FixableCacheEntry fce = (FixableCacheEntry) ce; 807 808 Object oid = ce.getCeIdentifier(); 809 State state = ws.lookup(oid); 810 if (state == null) { 811 state = readIntention(ws, ce, null); 812 } else if (stateManager.isDirty(state)) { 813 storage.write(ws.getConnectionHolder(), oid, state); 815 stateManager.makeFlushed(state); 816 } 817 ws.bind(VirtualState.instance, oid, WorkingSet.UNKNOWN_INTENTION); 822 823 try { 825 while (fce.getCeFixCount() > 0) { 826 cache.unfix(fce); 827 } 828 unbindManager.unbind(oid, true); 829 } catch (CacheException e) { 830 throw new PersistenceException("Impossible to unbind the entry: ", e); 831 } 832 833 stateManager.makeUnbound(ce); 835 stateManager.setReferenceState(ce, state); 837 } 838 839 public void refresh(WorkingSet ws, Object oid) throws PersistenceException { 840 assertOpenWorkingset(ws); 841 CacheEntry ce = cache.lookup(oid); 842 if (ce != null) { 843 refresh(ws, ce); 844 } 845 } 846 public void refresh(WorkingSet ws, CacheEntry ce) throws PersistenceException { 847 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 848 logger.log(BasicLevel.DEBUG, "refresh " + ce.getCeIdentifier()); 849 } 850 assertOpenWorkingset(ws); 851 stateManager.setReferenceState(ce, null); 854 ws.bind(VirtualState.instance, 857 ce.getCeIdentifier(), 858 WorkingSet.UNKNOWN_INTENTION); 859 } 860 861 868 public WorkingSet createWS(Object userObject) 869 throws PersistenceException { 870 WorkingSet ws = wsManager.createWS(userObject); 871 storage.beginWS(ws); 872 return ws; 873 } 874 875 883 public WorkingSet createWS(Object userObject, 884 Object workingSetType) 885 throws PersistenceException { 886 WorkingSet ws = wsManager.createWS(userObject, workingSetType); 887 storage.beginWS(ws); 888 return ws; 889 } 890 891 897 public void close(WorkingSet context) throws PersistenceException { 898 if (!context.entries().isEmpty()) { 899 boolean prepared_ok = false; 900 PersistenceException pe = null; 901 try { 902 prepared_ok = prepareWS(context, true); 903 } catch (PersistenceException e) { 904 pe = e; 905 } 906 if (prepared_ok) { 907 commitWS(context, WorkingSetLifeCycle.CLOSE_ACTION); 908 } else { 909 rollbackWS(context, WorkingSetLifeCycle.CLOSE_ACTION); 910 if (pe == null) { 911 throw new RolledBackPersistenceException(); 912 } else { 913 throw pe; 914 } 915 } 916 } else { 917 context.getConnectionHolder().closeCHConnection(); 918 context.setStatus(WorkingSetLifeCycle.getNextStatus( 919 context.getStatus(), WorkingSetLifeCycle.CLOSE_ACTION)); 920 storage.endWS(context); 921 } 922 wsManager.closeWS(context); 923 } 924 925 928 933 public void begin(TransactionalWorkingSet tx) throws PersistenceException { 934 assertOpenWorkingset(tx); 935 if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) { 936 logger.log(BasicLevel.DEBUG, "begin " + tx); 937 } 938 if (tx.entries().size() > 0) { 940 logger.log(BasicLevel.DEBUG, "Flush modification before the transaction " + tx); 941 close(tx); 942 } 943 tx.getConnectionHolder().begin(); 944 945 tx.setStatus(WorkingSetLifeCycle.getNextStatus( 947 tx.getStatus(), WorkingSetLifeCycle.BEGIN_TX_ACTION)); 948 } 949 950 958 public boolean prepare(TransactionalWorkingSet tx) throws PersistenceException { 959 assertOpenWorkingset(tx); 960 return prepareWS(tx, !tx.getWSRollBackOnly()); 961 } 962 963 970 public void commit(TransactionalWorkingSet tx) throws PersistenceException { 971 assertOpenWorkingset(tx); 972 if (tx.getStatus() == TransactionalWorkingSet.CTX_ACTIVE_TRANSACTIONAL) { 973 boolean prepared_ok = false; 975 PersistenceException pe = null; 976 try { 977 prepared_ok = prepareWS(tx, !tx.getWSRollBackOnly()); 978 } catch (PersistenceException e) { 979 pe = e; 980 } 981 if (prepared_ok) { 982 commitWS(tx, WorkingSetLifeCycle.COMMIT_ACTION); 983 } else { 984 rollbackWS(tx, WorkingSetLifeCycle.ROLLBACK_ACTION); 985 if (pe == null) { 986 throw new RolledBackPersistenceException(); 987 } else { 988 throw pe; 989 } 990 } 991 } else { 992 commitWS(tx, WorkingSetLifeCycle.COMMIT_ACTION); 993 } 994 storage.beginWS(tx); 995 } 996 997 1004 public void rollback(TransactionalWorkingSet tx) throws PersistenceException { 1005 assertOpenWorkingset(tx); 1006 try { 1007 prepareWS(tx, false); 1008 } catch (PersistenceException e) { 1009 logger.log(BasicLevel.WARN, "An error occris during the rollback operation", e); 1010 } 1011 rollbackWS(tx, WorkingSetLifeCycle.ROLLBACK_ACTION); 1012 storage.beginWS(tx); 1013 } 1014} 1015 | Popular Tags |