Commit releases (Non-TX) pessimistic unlocks too soon

Open
#9,726 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
java
Domain
databases

Research direction

Start with ODatabaseDocumentAbstract.rawBegin() and trace the lock lifecycle through currentTx.rollback(true, 0) and commitTransaction(), using the session.lock()/session.unlock() reproduction described. Add the planned two-thread regression test; done means waiting threads cannot update the ORID until the larger transaction has fully committed.

Written by the indexing model from the issue text.

Description

OrientDB Version: 3.1.12
Java Version: 11.0.11
OS: Windows 11

Expected behavior

When two or more threads are waiting in session.lock() for the same ORID for another thread which is in a (larger) transaction, when that transaction is committed it should complete the commit before releasing the ORID lock for the waiting threads.

Actual behavior

When two or more threads are waiting in session.lock() for the same ORID for another thread which is in a transaction, when that transaction is in the commit phase the lock is released and before it can complete the other threads go ahead and update the record. Because of this the commit will crash with a message the record was already updated.
Is see there is that ODatabaseDocumentAbstract.rawBegin() has this part:

 if (!currentTx.isActive() && iTx instanceof OTransactionOptimistic) {
      noTxLockedRecords = ((OTransactionAbstract) currentTx).getInternalLocks();
 }

But that only records the noTxLockedRecords when I remove "!currentTx.isActive() && " and still that does not solve the issue. As soon as currentTx.rollback(true, 0); executes the other threads will be et loose one by one and update the record with milliseconds while the commitTransaction takes much longer. I currently don't know the flow of the commit well enough to fix this myself.

Steps to reproduce

Create a thread that frequently does (on one specific record)

  • session.lock()
  • update the returned record
  • session.save()
  • session.unlock()

Create another thread that

  • session.begin()
  • session.lock() on the same record as the first thead
  • save some other vertexes
  • updates the same record as the first thread wants to update.
  • session.commit()

I'll write a unit test as soon as I have time.

Dominant language
Java
Stars
5k
Forks
868
Avg merge
15h 6m
Merged PRs (30d)
18

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from orientechnologies/orientdb

All issues in orientechnologies/orientdb

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.