From ebb61c104bdbaae885a80be9ec707f53c492b4dd Mon Sep 17 00:00:00 2001 From: mposolda Date: Mon, 7 Mar 2016 15:19:03 +0100 Subject: [PATCH] KEYCLOAK-2529 More proper handling of DB errors during migration --- .../jpa/DefaultJpaConnectionProviderFactory.java | 13 ++++++++++++- .../conn/DefaultLiquibaseConnectionProvider.java | 8 +++++--- .../services/resources/KeycloakApplication.java | 1 + 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java index 4d931488c2..8cae9299ff 100755 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/DefaultJpaConnectionProviderFactory.java @@ -184,13 +184,24 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide emf = Persistence.createEntityManagerFactory(unitName, properties); logger.trace("EntityManagerFactory created"); + } catch (Exception e) { + // Safe rollback + if (connection != null) { + try { + connection.rollback(); + } catch (SQLException e2) { + logger.warn("Can't rollback connection", e2); + } + } + + throw e; } finally { // Close after creating EntityManagerFactory to prevent in-mem databases from closing if (connection != null) { try { connection.close(); } catch (SQLException e) { - logger.warn(e); + logger.warn("Can't close connection", e); } } } diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java index d0c686a0fe..a011b4153a 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/conn/DefaultLiquibaseConnectionProvider.java @@ -93,9 +93,6 @@ public class DefaultLiquibaseConnectionProvider implements LiquibaseConnectionPr // Change command for creating lock and drop DELETE lock record from it SqlGeneratorFactory.getInstance().register(new CustomInsertLockRecordGenerator()); - - // We wrap liquibase update in CustomLockService provided by DBLockProvider. No need to lock inside liquibase itself. - LockServiceFactory.getInstance().register(new DummyLockService()); } @@ -127,6 +124,11 @@ public class DefaultLiquibaseConnectionProvider implements LiquibaseConnectionPr String changelog = (database instanceof DB2Database) ? LiquibaseJpaUpdaterProvider.DB2_CHANGELOG : LiquibaseJpaUpdaterProvider.CHANGELOG; logger.debugf("Using changelog file: %s", changelog); + + // We wrap liquibase update in CustomLockService provided by DBLockProvider. No need to lock inside liquibase itself. + // NOTE: This can't be done in baseLiquibaseInitialization() as liquibase always restarts lock service + LockServiceFactory.getInstance().register(new DummyLockService()); + return new Liquibase(changelog, new ClassLoaderResourceAccessor(getClass().getClassLoader()), database); } diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index 55feae3d93..5232588cfe 100644 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -166,6 +166,7 @@ public class KeycloakApplication extends Application { } catch (Exception e) { session.getTransaction().rollback(); logger.migrationFailure(e); + throw e; } finally { session.close(); }