[英]Can I use transactions with ALTER TABLE?
I'm a beginner (actually newbie) to SQL transactions, so I may be missing something obvious.我是 SQL 事务的初学者(实际上是新手),所以我可能会遗漏一些明显的东西。
I have this SQL code, that I'm trying to run through phpMyAdmin :我有这个 SQL 代码,我试图通过phpMyAdmin运行:
START TRANSACTION;
INSERT INTO `users` VALUES(NULL, 'User A', 'user.a@example.com', '4', 'User A');
INSERT INTO `users` VALUES(NULL, 'User B', 'user.b@example.com', '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;
Second ALTER
causes #1054 - Unknown column 'number' in 'users'
error.第二个
ALTER
导致#1054 - Unknown column 'number' in 'users'
错误中的#1054 - Unknown column 'number' in 'users'
。
But, when it happens in phpMyAdmin , I can see, that first two INSERT
s (or the entire transaction) is not rolled back.但是,当它发生在phpMyAdmin 中时,我可以看到,前两个
INSERT
(或整个事务)没有回滚。 The users
table does contain two new records. users
表确实包含两条新记录。
What am I missing?我错过了什么? phpMyAdmin doesn't support transactions?
phpMyAdmin 不支持交易? Or I don't understand, how transactions actually work, and this is pretty normal, that these two
INSERT
s are not rolled back in case of error?或者我不明白,事务实际上是如何工作的,这很正常,如果出现错误,这两个
INSERT
不会回滚?
Some statements (most notably DDL ) in MySQL cause an implicit commit before they are executed and cannot be rolled back - as such this prevents the prior DML changes from being rolled back as well. MySQL 中的一些语句(最明显的是DDL )在执行之前会导致隐式提交并且无法回滚- 因此这也防止了先前的 DML 更改被回滚。
The statements listed in this section (and any synonyms for them) implicitly end any transaction active in the current session, as if you had done a COMMIT before executing the statement .
本节中列出的语句(以及它们的任何同义词)隐式地结束当前会话中活动的任何事务,就好像您在执行语句之前已完成 COMMIT 一样。 As of MySQL 5.5.3, most of these statements also cause an implicit commit after executing;
从 MySQL 5.5.3 开始,大多数这些语句在执行后也会导致隐式提交; for additional details, see the end of this section.
有关其他详细信息,请参阅本节末尾。
Since ALTER TABLE
is one of the affected statements, the the SQL batch is effectively treated as:由于
ALTER TABLE
是受影响的语句之一,因此 SQL 批处理被有效地视为:
START TRANSACTION;
INSERT INTO `users` VALUES(NULL, 'User A', 'user.a@example.com', '4', 'User A');
COMMIT; -- prevents ROLLBACK of insert(s), even if DDL fails
ALTER TABLE `users` CHANGE `level` `level` TINYINT(3) UNSIGNED NOT NULL;
The suggested solution is to keep DDL and DML separated .建议的解决方案是将 DDL 和 DML 分开。 The documentation says:
文档说:
You should design your [DML] transactions not to include such [DDL] statements.
您应该设计您的 [DML] 事务以不包含此类 [DDL] 语句。 If you issue a statement early in a transaction that cannot be rolled back, and then another statement later fails, the full effect of the transaction cannot be rolled back in such cases by issuing a ROLLBACK statement.
如果您在无法回滚的事务中早期发出一条语句,然后另一条语句随后失败,则在这种情况下,无法通过发出 ROLLBACK 语句来回滚事务的全部效果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.