TransactionScopeKeyLocker implements KeyLocker { @Override public LockMonitor writeLock(final Object key, final long transactionId, final long timeout, final boolean strict) { final Map<Object, LockMonitor> locks = writeLocks; LockMonitor monitor = null; synchronized ( locks ) { monitor = locks.get( key ); if ( monitor == null ) { monitor = new LockMonitor( new TransactionModificationLock( strict ), key ); locks.put( key, monitor ); } monitor.acquires++; } try { boolean locked = timeout == Long.MAX_VALUE ? monitor.lock.lock( transactionId ) : monitor.lock.tryLock( transactionId, timeout, TimeUnit.MILLISECONDS ); return locked ? monitor : null; } catch ( InterruptedException e ) { Thread.currentThread().interrupt(); throw new SpaceException( Thread.currentThread().toString() + " has been interrupted", e ); } }  @Override LockMonitor writeLock(final Object key,
                                 final long transactionId,
                                 final long timeout,
                                 final boolean strict); @Override void writeUnlock(final EntryKeyLockQuard keyGuard,
                            final long transactionId);  }
@Test public void cantGetLockForTheSameKeyFromParallelTransaction() { keyLocker.writeLock( "abc", transactionID, 0, true ); assertThat( keyLocker.writeLock( "abc", transactionID + 1, 1, true ), is( nullValue() ) ); assertThat( keyLocker.writeLock( "abc", transactionID + 2, 0, true ), is( nullValue() ) ); }
@Test public void canDealWithThreadInterruption() throws InterruptedException { keyLocker.writeLock( "abc", transactionID, 0, true ); Thread t = new Thread() { @Override public void run() { keyLocker.writeLock( "abc", transactionID + 1, Long.MAX_VALUE / 2, true ); } }; t.start(); t.interrupt(); t.join(); }