[ 
https://issues.apache.org/jira/browse/IGNITE-21231?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

 Kirill Sizov updated IGNITE-21231:
-----------------------------------
    Description: 
h3. Motivation
If a lock key does not use the context id (_LockKey#contextId_ is _null_), it 
does not appear in the iterator. Here is a test that demonstrates incorrect 
behavior:
{code:title=AbstractLockManagerTest.java}
@Test
public void simpleTest() {
    UUID txId1 = TestTransactionIds.newTransactionId();
    LockKey key = new LockKey(0);
    lockManager.acquire(txId1, key, S).join();
    assertTrue(lockManager.locks(txId1).hasNext());
}
{code}

h3. Definition of done
Despite the fact that the method is used only in tests, it has to work 
correctly. All locks should be in the lock iterator.

h3. Issue details.
The real issue is way more serious than described in the motivation section.

HeapLockManager contains HeapUnboundedLockManager:
{code:title=HeapLockManager.java}
  public HeapLockManager() {
        this(new WaitDieDeadlockPreventionPolicy(), SLOTS, SLOTS, new 
HeapUnboundedLockManager());
    }
{code}

And this is how {{HeapLockManager.acquire}} looks like:
{code:title=HeapLockManager.java}
 public CompletableFuture<Lock> acquire(UUID txId, LockKey lockKey, LockMode 
lockMode) {
        if (lockKey.contextId() == null) { // Treat this lock as a hierarchy 
lock.
            return parentLockManager.acquire(txId, lockKey, lockMode);
        }
  ...
// the rest of the body is omitted
}
{code}

So if a lock key lacks context id, it is forwarded to parentLockManager. 
Unfortunately, it is the only place where the forwarding is used, other methods 
like release do not check context id.

Imagine the code
{code}
  LockKey key = new LockKey(0);
  lockManager.acquire(txId1, key, S).join();
  lockManager.release(txId1, key, S);
{code}

In this case the lock is present in the parentLockManager only and is not 
released with {{lockManager.release}}


  was:
h3. Motivation
If a lock key does not use the context id (_LockKey#contextId_ is _null_), it 
does not appear in the iterator. Here is a test that demonstrates incorrect 
behavior:
{code:title=AbstractLockManagerTest.java}
@Test
public void simpleTest() {
    UUID txId1 = TestTransactionIds.newTransactionId();
    LockKey key = new LockKey(0);
    lockManager.acquire(txId1, key, S).join();
    assertTrue(lockManager.locks(txId1).hasNext());
}
{code}

h3. Definition of done
Despite the fact that the method is used only in tests, it has to work 
correctly. All locks should be in the lock iterator.


> HeapLockManager#locks method do not provide all acuired locks
> -------------------------------------------------------------
>
>                 Key: IGNITE-21231
>                 URL: https://issues.apache.org/jira/browse/IGNITE-21231
>             Project: Ignite
>          Issue Type: Bug
>            Reporter: Vladislav Pyatkov
>            Priority: Major
>              Labels: ignite-3
>
> h3. Motivation
> If a lock key does not use the context id (_LockKey#contextId_ is _null_), it 
> does not appear in the iterator. Here is a test that demonstrates incorrect 
> behavior:
> {code:title=AbstractLockManagerTest.java}
> @Test
> public void simpleTest() {
>     UUID txId1 = TestTransactionIds.newTransactionId();
>     LockKey key = new LockKey(0);
>     lockManager.acquire(txId1, key, S).join();
>     assertTrue(lockManager.locks(txId1).hasNext());
> }
> {code}
> h3. Definition of done
> Despite the fact that the method is used only in tests, it has to work 
> correctly. All locks should be in the lock iterator.
> h3. Issue details.
> The real issue is way more serious than described in the motivation section.
> HeapLockManager contains HeapUnboundedLockManager:
> {code:title=HeapLockManager.java}
>   public HeapLockManager() {
>         this(new WaitDieDeadlockPreventionPolicy(), SLOTS, SLOTS, new 
> HeapUnboundedLockManager());
>     }
> {code}
> And this is how {{HeapLockManager.acquire}} looks like:
> {code:title=HeapLockManager.java}
>  public CompletableFuture<Lock> acquire(UUID txId, LockKey lockKey, LockMode 
> lockMode) {
>         if (lockKey.contextId() == null) { // Treat this lock as a hierarchy 
> lock.
>             return parentLockManager.acquire(txId, lockKey, lockMode);
>         }
>   ...
> // the rest of the body is omitted
> }
> {code}
> So if a lock key lacks context id, it is forwarded to parentLockManager. 
> Unfortunately, it is the only place where the forwarding is used, other 
> methods like release do not check context id.
> Imagine the code
> {code}
>   LockKey key = new LockKey(0);
>   lockManager.acquire(txId1, key, S).join();
>   lockManager.release(txId1, key, S);
> {code}
> In this case the lock is present in the parentLockManager only and is not 
> released with {{lockManager.release}}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to