Details
Description
This happened to me in 10.0 on WinXP; don't know about other platforms/versions.
First, I create a 2-rows table with a primary key. Then I start a transaction and invoke a function which tries to set both values to 10. The first value is updated, the second value fails (duplicate value), but the first operation is not rollback, so I get a row with id=10.
Here's the code:
DELIMITER || USE test; DROP TABLE IF EXISTS t1, t2; DROP FUNCTION IF EXISTS f1; CREATE TABLE t1 ( id TINYINT UNSIGNED PRIMARY KEY ) ENGINE=InnoDB; INSERT INTO t1 VALUES (1), (2); CREATE FUNCTION f1() RETURNS TEXT BEGIN DECLARE CONTINUE HANDLER FOR 1062 DO NULL; UPDATE t1 SET id = 10 ORDER BY id ASC; RETURN TRUE; END; || DELIMITER ; SET autocommit = 0; START TRANSACTION; SELECT f1(); COMMIT; SHOW WARNINGS; SELECT * FROM t1;
As far as I understand from this page, this is a bug:
http://dev.mysql.com/doc/refman/5.6/en/innodb-error-handling.html
"A duplicate-key error rolls back the SQL statement, if you have not specified the IGNORE option in your statement."
In my test a DECLARE CONTINUE HANDLER is used, but I couldn't find transaction information in the DECLARE HANDLER page or similar pages.
Gliffy Diagrams
Attachments
Issue Links
Activity
- All
- Comments
- Work Log
- History
- Activity
- Transitions
Hi Federico,
It seems to be a tricky issue.
On one hand, the current behavior looks logical me. You specifically instruct your function to ignore the duplicate key condition by adding an empty continue handler:
DECLARE CONTINUE HANDLER
FOR 1062
DO NULL;
If you hadn't done that, the result would have been as you expected.
On the other hand, it's not as obvious as a case with two subsequent updates would have been:
DECLARE CONTINUE HANDLER
FOR 1062
DO NULL;
UPDATE t1 SET id = 10 WHERE id = 1;
UPDATE t1 SET id = 10 WHERE id = 2;
Here one could totally expect the result of the first statement to be preserved; but should it be so inside a single statement? I can't say for certain one way or another. My bet is on "it's by design (of error handlers in stored procedures)", but if you have doubts, I can get a second opinion. Alternatively, you can try to file a bug at MySQL and see what they think about it (it works the same way in MySQL).
One thing is obvious though, the behavior of InnoDB error handling together with stored procedures error handling should be documented somewhere; maybe it is, but I couldn't find it. So, at least the doc request is due.