简体   繁体   English

我可以将事务与 ALTER TABLE 一起使用吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM