Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade lock not working correctly due to cache of ranChangeSetList #2816

Closed
joggeli34 opened this issue May 3, 2022 · 3 comments · Fixed by #3396
Closed

Upgrade lock not working correctly due to cache of ranChangeSetList #2816

joggeli34 opened this issue May 3, 2022 · 3 comments · Fixed by #3396

Comments

@joggeli34
Copy link

Environment

Liquibase Version: 4.9.0

Liquibase Integration & Version: Quarkus 2.8.1

Liquibase Extension(s) & Version:

Database Vendor & Version: PSQL

Operating System Type & Version:

Description

When creating a liquibase instance and use them for two commands, the lock is not working correctly.

We have following code:

  try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
          liquibase.validate();
          liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
  }

Following happens:

  • Inside the validate() method, the ranChangeSetList (from StandardChangeLogHistoryService) is created and filled with the values from the change log table
  • in the update() a lock on the table is created
    • the content on the table is not read again, the cached ranChangeSetList is used. -> so both services that loaded the ranChangeSetList before any change, will try to run the new changesets.
    • So the changesets are run twice

Steps To Reproduce

Create following code:

  try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
          liquibase.validate();
          Thread.sleep(1000);
          liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
  }

Run the code twice in parallel.

Actual Behavior

The new changesets will be applied twice.

Expected/Desired Behavior

The ranChangeSetList is revalidated during the duration of the lock, and so the changes are applied only once

@filipelautert
Copy link
Collaborator

Hi @joggeli34 - just a note that this error only happens when executing 2 processes: if you run 2 threads you get the following error:
Exception in thread "Thread-13" Exception in thread "Thread-12" java.lang.RuntimeException: liquibase.exception.LiquibaseException: java.lang.RuntimeException: Cannot end scope nvazcrkxnr when currently at scope awqeyfxdhb
at liquibase.dbtest.pgsql.RunnableProblem.run(PostgreSQLIntegrationTest.java:234)
at java.base/java.lang.Thread.run(Thread.java:829)

Anyway I'm working on that, thanks for the report.

@filipelautert
Copy link
Collaborator

filipelautert commented Oct 31, 2022

Hello @joggeli34

PR #3396 adresses this issue and will fix your scenario. But as you aim for performance, I would suggest another approach as using the current code you will be loading the changeset twice (one to validate and the second to update). My suggestion would be to manage the lock within your code, thus keeping the cache in memory. Something like that:

LockService lockService = LockServiceFactory.getInstance().getLockService(liquibase.getDatabase());
try {
	lockService.waitForLock();
	liquibase.validate();
	liquibase.update("test, context-b");
} finally {
	lockService.releaseLock();
}

By holding the lock you will prevent Liquibase from reloading the caches. This code works with current versions of Liquibase, you don't need to wait for the next release with the associated PR to start using it.

@joggeli34
Copy link
Author

Thanks a lot.

Yes we are using two separate processes (actually multiple docker container starting at the same time), this is when it happened.

I will add the lock to our custom code, thanks for this suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants