使用SQL脚本和事务管理mysql架构更改

时间:2010-08-05 10:07:49

标签: mysql transactions rollback

我正在使用PHP / MySQL应用程序中的多个数据库。我有开发,测试,登台和生产数据库以保持同步。

目前我们还在构建这个东西,所以很容易让它们保持同步。我使用我的dev db作为主人,当我想更新其他人时,我只是将他们核对并从我的脑筋中重新创建它们。但是,将来一旦有真实数据,我就无法做到这一点。

我想将SQL脚本编写为文本文件,我可以使用svn中随附的PHP更改进行编辑,然后在更新它们时将脚本应用于每个数据库实例。

我想使用事务,以便在脚本期间出现任何错误时,它将回滚所做的任何部分更改。所有表都是InnoDB

当我尝试添加已存在的列时,添加一个新列,如下所示:

SET FOREIGN_KEY_CHECKS = 0;
START TRANSACTION;
ALTER TABLE `projects` ADD COLUMN `foo1` varchar(255) NOT NULL after `address2`;
ALTER TABLE `projects` ADD COLUMN `foo2` varchar(255) NOT NULL after `address2`;
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

...它仍然提交新列,即使它没有添加第一个,当然,因为我发出了COMMIT而不是ROLLBACK。

我需要它在出错时有条件地发出回滚命令。如何在一个特殊的SQL脚本中执行此操作?

我知道存储过程的'声明退出处理程序'功能,但我不想存储它;我只是想把它作为一个adhoc脚本运行。

我是否需要将其转换为存储过程才能获得条件回滚,还是有另一种方法可以在单个adhoc SQL脚本中使整个事务成为原子?

欢迎使用示例的任何链接 - 我已经使用Google搜索,但到目前为止只找到存储过程示例

非常感谢

伊恩

编辑 - 这永远不会奏效;遇到ALTER TABLE会导致隐式提交:http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html感谢Brian提醒

1 个答案:

答案 0 :(得分:2)

前几天我了解到数据定义语言语句总是在MySQL中起作用,并导致事务在应用时提交。我想如果你想确保成功,你可能必须以交互方式做这件事。

我在这个讨论过的网站上找不到这个问题(仅在几天前)。

如果需要保持多个数据库同步,可以查看复制。尽管复制不容小觑,但它可能就是您所需要的。见http://dev.mysql.com/doc/refman/5.0/en/replication-features.html