ebean-orm / ebean-migration

DB Migration runner (similar to Flyway) which can be used standalone or with Ebean (run migrations on EbeanServer start)
Apache License 2.0
9 stars 5 forks source link

Race condition when creating db_migration table - Postgres can't continue - PSQLException: ERROR: current transaction is aborted #116

Closed rbygrave closed 2 years ago

rbygrave commented 2 years ago

With Postgres we need an explicit connection.rollback() when the MigrationTable.createTable() fails a race. Without the rollback the following check for the table existing fails with Postgres due to - ERROR: current transaction is aborted, commands ignored until end of transaction block

The fix is to add the explicit rollback() when the create table execution fails.


org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block: java.lang.RuntimeExceptionjava.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block  at io.ebean.migration.MigrationRunner.run(MigrationRunner.java:123) at io.ebean.migration.MigrationRunner.run(MigrationRunner.java:75)  at io.ebean.migration.MigrationRunner.run(MigrationRunner.java:68)  at io.ebean.migration.AutoRunner.run(AutoRunner.java:45)    at io.ebeaninternal.server.core.DefaultServer.start(DefaultServer.java:323) at io.ebeaninternal.server.core.DefaultContainer.startServer(DefaultContainer.java:154) at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:108)    at io.ebeaninternal.server.core.DefaultContainer.createServer(DefaultContainer.java:29) at io.ebean.DatabaseFactory.createInternal(DatabaseFactory.java:136)    at io.ebean.DatabaseFactory.create(DatabaseFactory.java:85) at nz.co.eroad.backport.config.DatabaseFactory.backport(DatabaseFactory.java:37)    at nz.co.eroad.backport.config.DatabaseFactory$DI.build_backport(DatabaseFactory$DI.java:31)    at nz.co.eroad.backport.BackportModule.build_ebean_Database_backport(BackportModule.java:137)   at nz.co.eroad.backport.BackportModule.build(BackportModule.java:91)    at io.avaje.inject.DBeanScopeBuilder.build(DBeanScopeBuilder.java:164)  at nz.co.eroad.backport.BackportSnsLambda.(BackportSnsLambda.java:31)   at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block  at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676)   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496)    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413)    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:333)   at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:319)   at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:295)   at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:244)   at org.postgresql.jdbc.PgDatabaseMetaData.getTables(PgDatabaseMetaData.java:1343)   at io.ebean.migration.runner.MigrationTable.tableExists(MigrationTable.java:266)    at io.ebean.migration.runner.MigrationTable.createIfNeededAndLock(MigrationTable.java:158)  at io.ebean.migration.MigrationRunner.run(MigrationRunner.java:108) ... 19 moreCaused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "pg_type_typname_nsp_index"  Detail: Key (typname, typnamespace)=(db_migration, 24586) already exists.   at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2676)   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2366) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:356) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:496)    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:413)    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:190)   at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:177)    at io.ebean.datasource.pool.ExtendedPreparedStatement.execute(ExtendedPreparedStatement.java:103)   at io.ebean.ddlrunner.DdlRunner.runStatement(DdlRunner.java:100)    at io.ebean.ddlrunner.DdlRunner.runStatements(DdlRunner.java:71)    at io.ebean.ddlrunner.DdlRunner.runAll(DdlRunner.java:54)   at io.ebean.migration.runner.MigrationScriptRunner.runScript(MigrationScriptRunner.java:34) at io.ebean.migration.runner.MigrationTable.createTable(MigrationTable.java:207)    at io.ebean.migration.runner.MigrationTable.createIfNeededAndLock(MigrationTable.java:156)  ... 20 more
--