1

我们在 GAE 上使用 Cloud SQL。一切都在本地开发服务器上运行良好。我们正在使用带有静态连接字符串的 AppEngineDriver。由于 Flyway 能够创建 schema_version 表,因此在生产环境中连接良好。

但随后我们得到一个错误,它无法锁定所述表。桌子是空的。我们有 3 次迁移,但没有一个被执行。

我们在 Spring 以 Java 配置样式创建 DataSource bean 时启动迁移。

这是堆栈跟踪。

非常感谢!

更新 1:我在第一个末尾添加了相关的辅助堆栈跟踪。

com.googlecode.flyway.core.api.FlywayException:无法锁定表ourschemaschema_version:java.sql.SQLException:com.google.cloud.sql 的 com.google.cloud.sql.jdbc.internal.Exceptions.newSqlException(Exceptions.java:219) 的准备好的语句协议尚不支持此命令。 jdbc.internal.SqlProtoClient.check(SqlProtoClient.java:198) 在 com.google.cloud.sql.jdbc.internal.SqlProtoClient.executeSql(SqlProtoClient.java:87) 在 com.google.cloud.sql.jdbc.internal。 com.google.cloud.sql.jdbc.Connection.executeSql(Connection.java:528) 处的 SqlProtoClient.executeSql(SqlProtoClient.java:76) com.google.cloud.sql.jdbc.PreparedStatement.executeSqlImpl(PreparedStatement.java: 141) 在 com.google.cloud.sql.jdbc.Statement.executeImpl(Statement.java:154) 在 com.google.cloud.sql.jdbc.PreparedStatement.execute(PreparedStatement.java:122) 在 com.googlecode.flyway .core.dbsupport.JdbcTemplate。在 com.googlecode.flyway.core.dbsupport.Table.lock(Table.java: 254) 在 com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:140) 在 com.googlecode 的 com.googlecode.flyway.core.metadatatable.MetaDataTableImpl.lock(MetaDataTableImpl.java:121)。 flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:138) 在 com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:54) 在 com.googlecode.flyway.core.command .DbMigrate.migrate(DbMigrate.java:137) 在 com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:862) 在 com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:815 ) 在 com.googlecode.flyway.core.Flyway.execute(Flyway.java:1177) 在 com.ourapplication.pilote.persistence.FlywayMigrationDataSourceInitializer.postInitialize(FlywayMigrationDataSourceInitializer.java:23) 在 com.ourapplication.pilote.persistence.PersistenceConfiguration 的 com.googlecode.flyway.core.Flyway.migrate(Flyway.java:815) .initializeDataSource(PersistenceConfiguration.java:188) 在 com.ourapplication.pilote.persistence.PersistenceConfiguration.dataSource(PersistenceConfiguration.java:175)数据源(PersistenceConfiguration.java:175)数据源(PersistenceConfiguration.java:175)

原因:java.sql.SQLException:com.google.cloud 的 com.google.cloud.sql.jdbc.internal.Exceptions.newSqlException(Exceptions.java:219) 的准备好的语句协议尚不支持此命令。 com.google.cloud.sql.jdbc.internal.SqlProtoClient.executeSql(SqlProtoClient.java:87) 上 com.google.cloud.sql.jdbc 上的 sql.jdbc.internal.SqlProtoClient.check(SqlProtoClient.java:198)。 internal.SqlProtoClient.executeSql(SqlProtoClient.java:76) 在 com.google.cloud.sql.jdbc.Connection.executeSql(Connection.java:528) 在 com.google.cloud.sql.jdbc.PreparedStatement.executeSqlImpl(PreparedStatement. java:141) 在 com.google.cloud.sql.jdbc.Statement.executeImpl(Statement.java:154) 在 com.google.cloud.sql.jdbc.PreparedStatement.execute(PreparedStatement.java:122) 在 com.googlecode .flyway.core.dbsupport.JdbcTemplate。在 com.googlecode.flyway.core.dbsupport.Table.lock(Table.java: 254)

4

1 回答 1

1

我有点困惑,因为 Flyway 文档说一切都可以在 GAE 上使用 Cloud SQL 和 AppEngineDriver。也许这是 Flyway 或 GAE 最近发生的变化。

但这是我的解决方法。

在使用 JAD 查看 GAE 的类并跟踪 Flyway 之后,我认为用于在 App Engine 服务器实例和 MySQL 集群之间发送查询的 RPC 协议不支持某些 SQL 语句,例如 LOCK。

所以一时兴起,我在 Flyway 中重写了 MySQLTable.java 以使用简单的 Statement 而不是 PreparedStatement。没有语句缓存,但它可以工作。

我刚刚将 MySQLTable.java 复制到我的项目中,保持相同的包装并替换了以下内容:

@Override
protected void doLock() throws SQLException
{
    jdbcTemplate.executeStatement("LOCK TABLES " + this + " WRITE");
}

@Override
protected void doUnlock() throws SQLException
{
    jdbcTemplate.executeStatement("UNLOCK TABLES");
}

执行语句而不是执行。

我们将等待官方修复。

问候,

雷米

于 2013-05-08T19:32:30.187 回答