使用MySQL START TRANSACTION时,MySQL决定回滚 - 如果一个表有一个AUTO_INCREMENT列 - 在回滚期间列是否会减少?
还是应该?
我遇到了正确回滚事务数据的一些问题 - 但看起来表格是自动递增的,而不是在回滚中递减。
# BOTH TABLES START OUT EMPTY // TABLE1 ID is **auto_increment**
START TRANSACTION;
INSERT INTO `TABLE1` (`ID` ,`NAME`) VALUES (NULL , 'Ted'); # MySQL TABLE1 **ID** is Auto incremented to 1
INSERT INTO `TABLE2` (`ID` ,`WRONGVALUE`) VALUES (NULL , 'some value'); # error. This TRANSACTION will not succeed
COMMIT; # Because of the error - this TRANSACTION is now rolled back and Ted is NOT added
因为MySQL会自动增加第一个表上的ID - 无论事务是成功还是失败 - 这是自己递减表的标准做法吗?
答案 0 :(得分:39)
不,自动增量机制必须在事务范围之外工作,因为在完成事务之前,另一个用户可能正在插入同一个表。在知道您的交易是否使用您刚刚分配的价值之前,其他用户的交易必须能够分配下一个值。
重新评论:如果我可以更清楚地说出来,可以回滚交易范围的任何变化。自动递增计数器不会回滚,因此它不遵守事务的原子性。它也不服从隔离,因为即使您的交易尚未提交,另一个交易也会获得下一个值。
自动增量的工作方式意味着有时候,如果插入一些行然后回滚事务,那么使用自动增量分配的值将永远丢失!
但这没关系。主键值必须是唯一的,但它们不需要是连续的。换句话说,它们不是行号,你不应该那样使用它们。所以你永远不需要减少自动增量创建的值。
答案 1 :(得分:0)
公开:我是SQL的新手,所以其中有些可能是错误的。但这就是我的理解。 自动增量功能必须在事务之外起作用,否则您可能会破坏数据。假设您有2个用户都试图连接到dB。两者都在创建帐户。创建帐户1时,它会增加到1。然后创建帐户2,它会增加到2。到目前为止,它看起来像下面的样子:
现在让我们说帐户2提交了,但是帐户1失败了。现在您的表如下所示:
由于您减少了自动增量,因此当某人尝试注册新帐户时,您将无法拥有唯一的值,因为该货币对将是:
这将失败,因为主键2不是唯一的。
如果您需要修复表(出于开发目的),则可以始终运行以下代码:
ALTER TABLE `DB_NAME`.`TABLE_NAME`
AUTO_INCREMENT = 1 (or some other number);