From 8da81efe902ceb9a106dff15ce44638c6be1eecc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 27 Apr 2024 07:46:24 -0700 Subject: Better DB lock error message --- src/main/java/org/traccar/Main.java | 11 +++++-- .../java/org/traccar/storage/DatabaseModule.java | 35 ++++++++++++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 33fcf654f..943b5bd7d 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -17,6 +17,7 @@ package org.traccar; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.ProvisionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; @@ -142,8 +143,14 @@ public final class Main { } })); } catch (Exception e) { - LOGGER.error("Main method error", e); - throw new RuntimeException(e); + Throwable unwrapped; + if (e instanceof ProvisionException) { + unwrapped = e.getCause(); + } else { + unwrapped = e; + } + LOGGER.error("Main method error", unwrapped); + System.exit(1); } } diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java index 9898a2fca..86e5267d4 100644 --- a/src/main/java/org/traccar/storage/DatabaseModule.java +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -20,10 +20,12 @@ import com.google.inject.Provides; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import liquibase.Contexts; +import liquibase.GlobalConfiguration; import liquibase.Liquibase; import liquibase.database.Database; import liquibase.database.DatabaseFactory; import liquibase.exception.LiquibaseException; +import liquibase.exception.LockException; import liquibase.resource.DirectoryResourceAccessor; import liquibase.resource.ResourceAccessor; import org.traccar.config.Config; @@ -83,16 +85,22 @@ public class DatabaseModule extends AbstractModule { ResourceAccessor resourceAccessor = new DirectoryResourceAccessor(new File(".")); - Database database = DatabaseFactory.getInstance().openDatabase( - config.getString(Keys.DATABASE_URL), - config.getString(Keys.DATABASE_USER), - config.getString(Keys.DATABASE_PASSWORD), - config.getString(Keys.DATABASE_DRIVER), - null, null, null, resourceAccessor); + System.setProperty("liquibase.changelogLockWaitTimeInMinutes", "1"); - try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { - liquibase.clearCheckSums(); - liquibase.update(new Contexts()); + try { + Database database = DatabaseFactory.getInstance().openDatabase( + config.getString(Keys.DATABASE_URL), + config.getString(Keys.DATABASE_USER), + config.getString(Keys.DATABASE_PASSWORD), + config.getString(Keys.DATABASE_DRIVER), + null, null, null, resourceAccessor); + + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } + } catch (LockException e) { + throw new DatabaseLockException(); } } @@ -100,3 +108,12 @@ public class DatabaseModule extends AbstractModule { } } + +class DatabaseLockException extends RuntimeException { + DatabaseLockException() { + super("Database is in a locked state. " + + "It could be due to early service termination on a previous launch. " + + "To unlock you can run this query: 'UPDATE DATABASECHANGELOGLOCK SET locked = 0'. " + + "Make sure the schema is up to date before unlocking the database."); + } +} -- cgit v1.2.3