2014-04-02 22 views
3

我是一个初学者(实际上是新手)SQL事务,所以我可能会漏掉一些明显的东西。我可以使用ALTER TABLE进行事务吗?

我有这样的SQL代码,我试图通过phpMyAdmin的运行:

START TRANSACTION; 

INSERT INTO `users` VALUES(NULL, 'User A', '[email protected]', '4', 'User A'); 
INSERT INTO `users` VALUES(NULL, 'User B', '[email protected]', '3', 'User B'); 

ALTER TABLE `users` CHANGE `level` `level` TINYINT(3) UNSIGNED NOT NULL; 
ALTER TABLE `users` CHANGE `number` `number` INT(10) UNSIGNED NOT NULL; 
ALTER TABLE `users` ADD COLUMN `number` INT(10) UNSIGNED NOT NULL AFTER `id`; 

COMMIT; 

正如你可能会看到,第二ALTER原因#1054 - Unknown column 'number' in 'users'错误。

但是,当它发生在phpMyAdmin,我可以看到,前两个INSERT(或整个事务)没有回滚。 users表确实包含两个新记录。

我错过了什么? phpMyAdmin不支持交易?或者我不明白,事务实际上是如何工作的,这很正常,这两个INSERT s在错误的情况下不会回滚?

+0

谢谢!完美的答案。请重新编辑这个全功能的答案,这样我就可以挑选它并带给你一些代表。 – trejder

回答

4

某些语句(最值得注意的是DDL)在MySQL cause an implicit commit之前它们被执行和cannot be rolled back - 因为这防止了这样的现有DML被回滚,以及变化。

在本节(和任何同义词他们的)中列出的语句隐含主动结束当前会话中的任何交易,因为如果你做了执行该语句之前提交。从MySQL 5.5.3开始,这些语句中的大多数在执行后也会导致隐式提交;有关更多详细信息,请参阅本节的结尾。

由于ALTER TABLE是受影响的语句中的一个,该SQL批处理被有效地视为:

START TRANSACTION; 
INSERT INTO `users` VALUES(NULL, 'User A', '[email protected]', '4', 'User A'); 

COMMIT; -- prevents ROLLBACK of insert(s), even if DDL fails 
ALTER TABLE `users` CHANGE `level` `level` TINYINT(3) UNSIGNED NOT NULL; 

建议的解决方案是keep DDL and DML separateddocumentation说:

你应该设计你的[DML]交易不包括这样的[DDL]语句。如果您在事务中提前发出一个无法回滚的语句,然后另一个语句以后失败,那么通过发出ROLLBACK语句,在这种情况下无法回滚事务的完整效果。

相关问题