FlywayDB:迁移失败,执行语句"错误,但手动运行迁移SQL代码有效

时间:2014-04-12 02:55:10

标签: mysql scala playframework database-migration flyway

我有一个播放框架2.2.2 scala应用程序并使用play-flyway 1.0.3。

以下迁移应由flyway运行:

ALTER TABLE  `user_visits` ADD  `FirstSiteRequestTime` DATETIME NOT NULL ;
UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1) ;

所以我在表中添加一列,然后使用更新语句以编程方式填充它。

第一行执行正常,但更新statemens失败并带有

FlywaySqlScriptException: Error executing statement at line 2: UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1)
com.googlecode.flyway.core.command.FlywaySqlScriptException: Error executing statement at line 2: UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1)
com.googlecode.flyway.core.dbsupport.SqlScript.execute(SqlScript.java:92)
com.googlecode.flyway.core.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:72)
com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:243)
com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:241)
com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:72)

但是,当我使用迁移SQL代码并使用phpmyadmin运行它时,它运行正常(尽管运行需要2-5秒,表格非常大)。

我的mysql.log看起来像

                  128 Query SET autocommit=0
                  128 Query ALTER TABLE  `user_visits` ADD  `FirstSiteRequestTime` DATETIME NOT NULL
140412  4:40:43   128 Query UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1)
140412  4:40:44   128 Query rollback
                  128 Query SET autocommit=1

flyway是否有某种超时?日志文件显示它将查询发送到mysql服务器,但随后回滚。为什么?如前所述,查询是正确的。它在我手动运行时有效。

修改

运行迁移后,执行并提交了ALTER TABLE语句(表已更改),尽管mysql.log表示已回滚。第二个命令真的回滚了。

我还尝试在两次迁移中拆分两个SQL命令。然后第一个(ALTER TABLE)运行正常,第二个运行失败。

EDIT2

可能是某种超时问题。使其执行得更快(仅通过更新某些行)

ALTER TABLE  `user_visits` ADD  `FirstSiteRequestTime` DATETIME NOT NULL ;
UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1) WHERE user_visits.id<1000;

也正好在飞路上运行。

1 个答案:

答案 0 :(得分:0)

MySQL documentation表示自MySQL 5.5.3起,&#34;大多数陈述&#34;在执行之前导致隐式提交也会在执行之后执行此操作。这似乎包括ALTER TABLE语句(在MySQL 5.5.3及更高版本中)。

请注意,在问题中显示的日志中,autocommit处于禁用状态。可以肯定的是,要么在这些语句之间使用明确的COMMIT

ALTER TABLE  `user_visits` ADD  `FirstSiteRequestTime` DATETIME NOT NULL ;
COMMIT ;
UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1) ;

或将它们放在单独且连续的迁移文件中,如下所示:

文件V1__alter_table.sql:

ALTER TABLE  `user_visits` ADD  `FirstSiteRequestTime` DATETIME NOT NULL ;

文件V2__update_table.sql:

UPDATE `user_visits` SET `FirstSiteRequestTime`=(SELECT `Time` FROM `user_siterequests` WHERE `user_siterequests`.`Visit`=`user_visits`.`ID` ORDER BY `Time` ASC LIMIT 1) ;