我有一个播放框架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;
也正好在飞路上运行。
答案 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) ;