Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (c) 2010-2011. Axon Framework
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 
 package org.axonframework.repository;
 
 
Implementation of the LockManager that uses a pessimistic locking strategy. Calls to obtainLock will block until a lock could be obtained. If a lock is obtained by a thread, that thread has guaranteed unique access.

Author(s):
Allard Buijze
Since:
0.3
 
 class PessimisticLockManager implements LockManager {
 
     private final ConcurrentHashMap<StringDisposableLocklocks = new ConcurrentHashMap<StringDisposableLock>();

    
 
     @Override
     public boolean validateLock(AggregateRoot aggregate) {
         AggregateIdentifier aggregateIdentifier = aggregate.getIdentifier();
 
         return isLockAvailableFor(aggregateIdentifier)
                 && lockFor(aggregateIdentifier).isHeldByCurrentThread();
     }

    
Obtain a lock for an aggregate. This method will block until a lock was successfully obtained.

Parameters:
aggregateIdentifier the identifier of the aggregate to obtains a lock for.
 
     @Override
     public void obtainLock(AggregateIdentifier aggregateIdentifier) {
         boolean lockObtained = false;
         while (!lockObtained) {
             createLockIfAbsent(aggregateIdentifier);
             DisposableLock lock = lockFor(aggregateIdentifier);
             lockObtained = lock.lock();
             if (!lockObtained) {
                 .remove(aggregateIdentifierlock);
             }
         }
     }

    
Release the lock held on the aggregate. If no valid lock is held by the current thread, an exception is thrown.

Parameters:
aggregateIdentifier the identifier of the aggregate to release the lock for.
Throws:
java.lang.IllegalStateException if no lock was ever obtained for this aggregate
java.lang.IllegalMonitorStateException if a lock was obtained, but is not currently held by the current thread
 
     @Override
     public void releaseLock(AggregateIdentifier aggregateIdentifier) {
         Assert.state(.containsKey(aggregateIdentifier.asString()), "No lock for this aggregate was ever obtained");
         DisposableLock lock = lockFor(aggregateIdentifier);
         lock.unlock(aggregateIdentifier);
     }
 
     private void createLockIfAbsent(AggregateIdentifier aggregateIdentifier) {
         if (!.contains(aggregateIdentifier)) {
             .putIfAbsent(aggregateIdentifier.asString(), new DisposableLock());
         }
     }
 
     private boolean isLockAvailableFor(AggregateIdentifier aggregateIdentifier) {
         return .containsKey(aggregateIdentifier.asString());
     }
 
     private DisposableLock lockFor(AggregateIdentifier aggregateIdentifier) {
         return .get(aggregateIdentifier.asString());
     }
 
     private final class DisposableLock {
 
         private final ReentrantLock lock;
         // guarded by "lock"
         private volatile boolean isClosed = false;
        private DisposableLock() {
            this. = new ReentrantLock();
        }
        private boolean isHeldByCurrentThread() {
            return .isHeldByCurrentThread();
        }
        private void unlock(AggregateIdentifier aggregateIdentifier) {
            .unlock();
            disposeIfUnused(aggregateIdentifier);
        }
        private boolean lock() {
            .lock();
            if () {
                .unlock();
                return false;
            }
            return true;
        }
        private void disposeIfUnused(AggregateIdentifier aggregateIdentifier) {
            if (.tryLock()) {
                try {
                    if (.getHoldCount() == 1) {
                        // we now have a lock. We can shut it down.
                         = true;
                        .remove(aggregateIdentifier.asString(), this);
                    }
                } finally {
                    .unlock();
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X