MySQL AUTO_INCREMENT does not ROLLBACK

It can't work that way. Consider:

  • program one, you open a transaction and insert into a table FOO which has an autoinc primary key (arbitrarily, we say it gets 557 for its key value).
  • Program two starts, it opens a transaction and inserts into table FOO getting 558.
  • Program two inserts into table BAR which has a column which is a foreign key to FOO. So now the 558 is located in both FOO and BAR.
  • Program two now commits.
  • Program three starts and generates a report from table FOO. The 558 record is printed.
  • After that, program one rolls back.

How does the database reclaim the 557 value? Does it go into FOO and decrement all the other primary keys greater than 557? How does it fix BAR? How does it erase the 558 printed on the report program three output?

Oracle's sequence numbers are also independent of transactions for the same reason.

If you can solve this problem in constant time, I'm sure you can make a lot of money in the database field.

Now, if you have a requirement that your auto increment field never have gaps (for auditing purposes, say). Then you cannot rollback your transactions. Instead you need to have a status flag on your records. On first insert, the record's status is "Incomplete" then you start the transaction, do your work and update the status to "compete" (or whatever you need). Then when you commit, the record is live. If the transaction rollsback, the incomplete record is still there for auditing. This will cause you many other headaches but is one way to deal with audit trails.


I had a client needed the ID to rollback on a table of invoices, where the order must be consecutive

My solution in MySQL was to remove the AUTO-INCREMENT and pull the latest Id from the table, add one (+1) and then insert it manually.

If the table is named "TableA" and the Auto-increment column is "Id"

INSERT INTO TableA (Id, Col2, Col3, Col4, ...)
VALUES (
(SELECT Id FROM TableA t ORDER BY t.Id DESC LIMIT 1)+1,
Col2_Val, Col3_Val, Col4_Val, ...)

Let me point out something very important:

You should never depend on the numeric features of autogenerated keys.

That is, other than comparing them for equality (=) or unequality (<>), you should not do anything else. No relational operators (<, >), no sorting by indexes, etc. If you need to sort by "date added", have a "date added" column.

Treat them as apples and oranges: Does it make sense to ask if an apple is the same as an orange? Yes. Does it make sense to ask if an apple is larger than an orange? No. (Actually, it does, but you get my point.)

If you stick to this rule, gaps in the continuity of autogenerated indexes will not cause problems.