Leandro Bardelli
Leandro Bardelli

Reputation: 11608

MySQL with rollback transaction: is real?

Why MySQL does the insert row and then delete it if a rollback is called?

For e.g. with the following code:

declare exit handler for not found rollback;
declare exit handler for sqlwarning rollback;
declare exit handler for sqlexception

BEGIN
select last_insert_id();
rollback;
END;

START TRANSACTION;

INSERT INTO test (text) VALUES ('this_insert_works');
INSERT INTO test (id, text) VALUES (3,'this_insert_fails');

On the following code on a store procedure, if I execute it, and then I execute it again without the last line (it will work) I can see a "missing auto_increment ID" because the row was inserted and then, removed. The select returned returns an ID that doesn't exists.

How can avoid this behavior?

Upvotes: 2

Views: 390

Answers (1)

cdhowie
cdhowie

Reputation: 169478

You can't avoid this behavior.

Say you have two concurrently-running transactions and they both insert some records into test inside of a transaction. What will their id values be? What should happen if you commit one but roll back the other?

The only feasible option is to increment the table's auto_increment counter; since each transaction can't see each other's rows (but the rows do exist inside of their respective transactions), this is the only way to ensure that they both get a unique id.

While this behavior may appear undesirable, it's actually there for a very good reason. The only other option would be to lock the entire table when doing an INSERT inside of a transaction, preventing every other connection from inserting rows into that table at the same time. This would be terrible for performance.

Upvotes: 3

Related Questions