2013-05-08 3 views
1

Мы находимся на GAE с облачным SQL. Все отлично работает на локальном dev-сервере. Мы используем приложение AppEngineDriver со статической строкой подключения. Соединение хорош в производственной среде, поскольку Flyway смогла создать таблицу schema_version.Проблема в Google App Engine GAE: невозможно заблокировать таблицу schema_version

Но тогда мы получаем сообщение об ошибке, что он не может заблокировать указанную таблицу. Стол пуст. У нас есть 3 миграции, и ни одна из них не была выполнена.

Мы запускаем миграцию в то время, когда Spring создает компонент DataSource в стиле конфигурации Java.

Вот трассировка стека.

Большое спасибо!

Обновление 1: Я добавил дополнительную вторичную трассировку стека в конце первой.

com.googlecode.flyway.core.api.FlywayException: невозможно заблокировать таблицу ourschema. schema_version: java.sql.SQLException: эта команда не поддерживается в протоколе подготовленного протокола еще по адресу com.google.cloud.sql.jdbc.internal.Exceptions.newSqlException (Exceptions.java:219) at com.google. cloud.sql.jdbc.internal.SqlProtoClient.check (SqlProtoClient.java:198) at com.google.cloud.sql.jdbc.internal.SqlProtoClient.executeSql (SqlProtoClient.java:87) at com.google.cloud. sql.jdbc.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) at com.google.cloud.sql.jdbc.PreparedStatement.execute (PreparedStatement.java:122) на com.googlecode.flyway.core.dbsupport.JdbcTemplate.execute (JdbcTemplate.java:214) на com.googlecode.flyway. core.dbsupport.mysql.MySQLTable.doLock (MySQLTable.java:58) на com.googlecode.flyway.core.dbsupport.Table.lock (Table.java:254) на com.googlecode.flyway.core.metadatatable. MetaDataTableImpl.lock (MetaDataTableImpl.java:121) на com.googlecode.flyway.core.command.DbMigrate $ 1.doInTransaction (DbMigrate.java:140) на com.googlecode.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.Foreway $ 1.execute (Flyway.java:862) на com.googlecode.flyway.core.Flyway $ 1.execute (Flyway.java:815) at com.googlecode.flyway.core.Flyway.execute (Flyway.java:1177) at com.googlecode.flyway.core.Flyway.migrate (Flyway.java:815) at com.ourapplication.pilote.persistence.FlywayMigrationDataSourceInitializer. postInitialize (FlywayMigrationDataSourceInitializer.java:23) на com.ourapplication.pilote.persistence.PersistenceConfiguration.initializeDataSource (PersistenceConfiguration.java:188) на com.ourapplication.pilote.persistence.PersistenceConfiguration.dataSource (PersistenceConfiguration.java:175)

C aused by: java.sql.SQLException: эта команда не поддерживается в подготовленном протоколе протокола еще по адресу com.google.cloud.sql.jdbc.internal.Exceptions.newSqlException (Exceptions.java:219) at com.google. cloud.sql.jdbc.internal.SqlProtoClient.check (SqlProtoClient.java:198) at com.google.cloud.sql.jdbc.internal.SqlProtoClient.executeSql (SqlProtoClient.java:87) at com.google.cloud.sql.jdbc.internal.SqlProtoClient.executeSql (SqlProtoClient.java:76) at com.google.cloud.sql.jdbc.Connection.executeSql (Connection.java:528) at com.google.cloud.sql.jdbc.PreparedStatement.executeSqlImpl (PreparedStatement.java:141) at 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.execute (JdbcTemplate.java:214) в com.googlecode. flyway.core.dbsupport.mysql.MySQLTable.doLock (MySQLTable.java:58) на com.googlecode.flyway.core.dbsupport.Table.lock (Table.java:254)

ответ

1

Я немного смущен, потому что документы Flyway говорят, что все работает на GAE с Cloud SQL и AppEngineDriver. Может быть, это недавнее изменение либо на Flyway, либо на GAE.

Но вот мое исправление.

После использования JAD для изучения классов GAE, а также для отслеживания Flyway, я считаю, что некоторые операторы SQL, такие как LOCK, не поддерживаются протоколом RPC, используемым для отправки запросов между экземпляром сервера App Engine и кластером MySQL.

Так что, по прихоти, я переопределил MySQLTable.java в Flyway, чтобы использовать простое заявление вместо 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"); 
} 

executeStatement вместо выполнения.

Мы будем ждать официального исправления.

С уважением,

Remy

+1

Последняя версия кода уже вернулась к SELECT ... FOR UPDATE из-за дополнительных проблем, с помощью LOCK TABLES. Следующий выпуск должен снова работать из коробки. –