是否存在用于在一定时间后或在应用重启时自动删除LiquiBase DATABASE CHANGELOGLOCK的配置? [英] Is there a configuration for removing LiquiBase DATABASE CHANGELOGLOCK automatically after a certain time or on app restart?

查看:102
本文介绍了是否存在用于在一定时间后或在应用重启时自动删除LiquiBase DATABASE CHANGELOGLOCK的配置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有SpringBoot 2驱动的HA Java应用程序,其中我们在下面使用PostgreSQL.

We have SpringBoot 2 driven HA java application in which we use PostgreSQL underneath.

由于诸如意外崩溃或异常之类的某些原因,Liquibase最终以陈旧的DATABASECHANGELOGLOCK锁定,从未释放.

For certain reasons like unexpected crashes or Exceptions, Liquibase ends up with a stale DATABASECHANGELOGLOCK which was never released.

这导致应用程序的后续部署失败,应用程序等待更改锁定,然后退出,如下所示:

This results in subsequent deployments of the app failing with app waiting for the change lock and then exiting as follows:

   2020-03-04T11:10:31.78+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:31.78+0200 Waiting for changelog lock....
   2020-03-04T11:10:32.87+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:32.87+0200 Waiting for changelog lock....
   2020-03-04T11:10:41.78+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:41.78+0200 Waiting for changelog lock....
   2020-03-04T11:10:42.87+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:42.87+0200 Waiting for changelog lock....
   2020-03-04T11:10:51.79+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:51.79+0200 Waiting for changelog lock....
   2020-03-04T11:10:52.88+0200 SELECT LOCKED FROM public.databasechangeloglock WHERE ID=1
   2020-03-04T11:10:52.88+0200 Waiting for changelog lock....
   2020-03-04T11:10:54.00+0200 ERR 2020-03-04 09:10:54.010 UTC
   2020-03-04T11:10:55.88+0200 [HEALTH/0] ERR Failed to make TCP connection to port 8080: connection refused
   2020-03-04T11:10:55.88+0200 [CELL/0] ERR Failed after 1m0.626s: readiness health check never passed.
   2020-03-04T11:10:55.89+0200 [CELL/SSHD/0] OUT Exit status 0
   2020-03-04T11:10:55.89+0200 info    [native] Initiating shutdown sequence for Java agent
   2020-03-04T11:10:55.89+0200 info    [] Connection Status (120 times 300s)      : 0909

是否存在用于在一定时间后自动删除Liquibase DATABASECHANGELOGLOCK的配置,或者如果它早于5分钟或预定义的时间段,则在应用程序启动时将其删除.还是可以在Postgres开始寻找变更锁之前在App Start上以编程方式完成此操作.

Is there a configuration for removing Liquibase DATABASECHANGELOGLOCK automatically after a certain time or removing it on application start if it is older than let's say 5 mins or a predefined time period. Or can this be done programatically at App Start before Postgres starts looking for the change lock.

推荐答案

因此,我可以通过以下方法实现这一目标:

So I was able to achieve this via the following approach:

我们使用SpringLiquibase bean初始化LiquiBase.

We initialise LiquiBase using a SpringLiquibase bean.

在此bean中,在构造Liquibase实例之前,我调用了一种方法,该方法使用Statements向数据库查询锁,如果有任何超过5分钟的锁,我们将其删除.

Within this bean, before the Liquibase instance is constructed, I called a method which uses Statements to query the database for a lock, and if there are any locks older than 5 minutes, we delete them.

 @Bean
 public SpringLiquibase liquibase(DataSource dataSource) {
        // Added a hook to check for locks before LiquiBase initialises.
        removeDBLock(dataSource);
        //
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog(Constants.DDL_XML);
        liquibase.setDataSource(dataSource);
        return liquibase;
    }



 private void removeDBLock(DataSource dataSource) {
   
    //Timestamp, currently set to 5 mins or older.

    final Timestamp lastDBLockTime = new Timestamp(System.currentTimeMillis() - (5 * 60 * 1000));
    
    final String query = format("DELETE FROM DATABASECHANGELOGLOCK WHERE LOCKED=true AND LOCKGRANTED<'%s'", lastDBLockTime.toString());
    

    try (Statement stmt = dataSource.getConnection().createStatement()) {

        int updateCount = stmt.executeUpdate(query);
        if(updateCount>0){
            log.error("Locks Removed Count: {} .",updateCount);
        }
    } catch (SQLException e) {
        log.error("Error! Remove Change Lock threw and Exception. ",e);
    }
}

这篇关于是否存在用于在一定时间后或在应用重启时自动删除LiquiBase DATABASE CHANGELOGLOCK的配置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆