Liquibase rollback from command line not working

点点圈 提交于 2021-02-19 07:32:50

问题


I am doing an tomcat appliaction in a windows enviroment that when deployed creates/updates the DB Schema on the oracle db. For this I am using the Liquibase SDK 3.3.2. So basically I call the SDK an tell it to do an update from my changelog.xml. This parts works as fine. The code form the java class

...
Liquibase liquibase = new Liquibase(CHANGE_LOG,
                new ClassLoaderResourceAccessor(getClass().getClassLoader()), db);

liquibase.update("");

The problem is, when something goes wrong and I do a Rollback from the command line nothing happens. I get no exceptions or error messages. Just a message "Rollback succesfull", but in the DB there is no change at all. Now the funny thing is when I do the update for my change log file from cmd and then do the rollback also from the cmd then the Rollback works. The command line call looks as following:

Liquibase --changeLogFile=C:\myProject\src\main\resources\database\master.xml  --logLevel=DEBUG rollbackCount 5

My liquibase.properties file looks as following:

driver: oracle.jdbc.OracleDriver 
classpath:ojdbc6.jar 
url: jdbc:oracle:thin:@192.168.56.101:1521:orcl
username: myUser
password: mypassword

The question does some know why does this happens? Are there any incompatibilties between SDK and cmd tool?


回答1:


The problem was the path to the change log file. Liquibase stores somewhere the path to the chengeLog and comapres it to the given change log at calling. If they are not the same Liquibase will just go on without a changeLog and warning.

So in my case when calling Liquibase from the tomcat app the path was: database\master.xml and when calling it from the console I gave the path C:\myProject\src\main\resources\database\master.xml in the comand line. This caused the method to return null although Liquibase knew the path to the changeLog. So that was the reason it did not worked.

A workaround is to call liquibase from the command line from the same folder as the application did using a relative path.

Technical reason: After debuggin LB I found this. The Method DatabaseChageLog.getChangeSet() is returning null althoug the chanegeLog path is correct. This happens when creating the ChangeLogIterator for runnign the RollbackVisitor in the method Liquibase.rollback(int changesToRollback, Contexts contexts, LabelExpression labelExpression). This do not happens with the ValidationVisitor becasuse the ChangeLogIterator is created differently, that is why I did not get any error\warnings




回答2:


For the benefit of other readers, I'd like to add my experiences and understanding.

It's important to understand what is happening when you run a rollback from the command line

  • Liquibase consults the changelog file you provided via the --changeLogFile argument.

  • It will iterate through the changesets mentioned in this file, comparing their checksum to the checksum for the corresponding record in the DATABASECHANGELOG database table.

  • Now here's the important bit: the checksum is calculated from the filename (including the path) and the file contents.

  • If the checksums do not match, the changeset is not eligible for rollback.

  • If you ran Liquibase from inside a web-application, the chances are that the Liquibase changelog was located on the classpath, which means that the filename column in the DATABASECHANGELOG table is prefixed with classpath:

ID                  AUTHOR   FILENAME                                          
CreateWidgetTable   NabilH   classpath:liquibase/sprint1/create.widget.table.xml
  • This is not the case when you run via the command line

  • This will cause the checksum validation to fail and changeset to be ignored

However, I think there is a better solution than what you have proposed. You can point the --classpath argument of Liquibase command line at your WAR, and specify the --changeLogFilePath relative to the classpath.

Assume that I store my changelog in src/main/resources/liquibase/changelog.xml.

On the classpath therefore, this file is accessible via liquibase/changelog.xml.

java -jar lib/liquibase-core-3.5.3.jar\
    --url=jdbc:h2:tcp://localhost/~/test --username=sa --password=\
    --logLevel=DEBUG --classpath=/opt/tomcat9/webapps/springLiquibase.war\
    --changeLogFile=liquibase/changelog.xml rollback v1


来源:https://stackoverflow.com/questions/29147769/liquibase-rollback-from-command-line-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!