【发布时间】:2021-09-28 07:31:39
【问题描述】:
我已经设置了一个 DropWizard 服务,以便在应用启动时自动进行任何 Liquibase 迁移。
当我第一次启动我的 Dropwizard 服务时,我会运行 Liquibase::listLocks() 以提供信息。此调用还将创建 DATABASECHANGELOG 和 DATABASECHANGELOGLOCK 表(如果它们不作为副作用存在)。
曾经在新的 Oracle ATP DB 上,在调用 listLocks 期间创建 Lock 表时引发以下错误:
ERROR 2021-07-08 17:59:22,546 [main] com.blah.utils.LiquibaseMigrator: Error listing locks!
liquibase.exception.DatabaseException: ORA-12838: cannot read/modify an object after modifying it in parallel
[Failed SQL: (12838) INSERT INTO DATABASECHANGELOGLOCK (ID, LOCKED) VALUES (1, 0)]
at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:430)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:87)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:159)
at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:139)
at liquibase.lockservice.StandardLockService.init(StandardLockService.java:128)
at liquibase.Liquibase.checkLiquibaseTables(Liquibase.java:1176)
at liquibase.Liquibase.listLocks(Liquibase.java:1193)
at com.blah.utils.LiquibaseMigrator.dbLocksExist(LiquibaseMigrator.java:xxx)
at com.blah.utils.LiquibaseMigratorExecutor.dbLocksExist(LiquibaseMigratorExecutor.java:xxx)
at com.blah.MyApp.migrateDatabase(MyApp.java:xxx)
at com.blah.MyApp.run(MyApp.java:xxx)
at com.blah.MyApp.run(MyApp.java:xxx)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:59)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:98)
at io.dropwizard.cli.Cli.run(Cli.java:78)
at io.dropwizard.Application.run(Application.java:94)
at com.blah.MyApp.main(MyApp.java:xxx)
Caused by: java.sql.SQLException: ORA-12838: cannot read/modify an object after modifying it in parallel
服务会抛出该异常,然后 pod 会重新启动并重复。我手动将该行添加到它试图插入那里的锁表中,并且下一次启动成功。
当时只有 1 个 pod 正在运行,所以我认为它与我发现的这个 Race Condition on startup 错误无关,但我不知道它为什么/如何进入这个 @987654326 @状态。
【问题讨论】:
-
它与竞争条件无关。 liquibase 脚本很可能正在插入带有附加提示或并行提示的数据,然后尝试另一个插入而没有提交。
标签: java oracle liquibase dropwizard oracle-cloud-infrastructure