17

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をauto_incrementするので(トランザクションが成功したか失敗したかに関係なく)、これがテーブルを自分でデクリメントするための標準的な方法ですか?

4

2 に答える 2

48

いいえ、トランザクションを終了する前に別のユーザーが同じテーブルに挿入している可能性があるため、自動インクリメント メカニズムはトランザクションの範囲外で動作する必要があります。他のユーザーのトランザクションは、トランザクションが割り当てたばかりの値を使用しているかどうかを知る前に、次の値を割り当てることができる必要があります。

あなたのコメントについて: もっと明確に言えば、トランザクションの範囲の変更はロールバックされる可能性があります。自動インクリメント カウンターはロールバックされないため、トランザクションの原子性には従いません。トランザクションがまだコミットされていなくても、別のトランザクションが次の値を取得するため、分離にも従いません。

自動インクリメントの仕組みは、いくつかの行を挿入してからトランザクションをロールバックすると、自動インクリメントで割り当てた値が永久に失われることがあることを意味します!

しかし、これは大丈夫です。主キーの値は一意である必要がありますが、連続している必要はありません。つまり、これらは行番号ではないので、そのように使用すべきではありません。したがって、自動インクリメントによって作成された値をデクリメントする必要はありません。

于 2013-02-07T18:49:47.663 に答える