Search code examples
sqlmysqltransactionsstored-functions

Does stored function roll back the entire transaction?, is there an error in the documentation?


https://dev.mysql.com/doc/refman/8.0/en/commit.html

If a SELECT statement within a transaction calls a stored function, and a statement within the stored function fails, that statement rolls back. If ROLLBACK is executed for the transaction subsequently, the entire transaction rolls back.

Could you give me an example of that part of the documentation?

From my understanding if the stored function fails the whole transaction will fail, not just the SELECT a_stored_function();

I am confused, is there an error in the documentation?


Solution

  • create table t (
      id serial primary key,
      word text
    );
    
    delimiter ;;
    
    create function f(p_v text) returns int
    no sql
    begin
      declare v varchar(3);
    
      set v = p_v;
    
      return 0;
    end;;
    
    delimiter ;
    
    start transaction;
    
    insert into t (word) values ('bird');
    
    select f('too long');
    
    commit;
    
    select * from t;
    

    This deliberately causes an error in the function, by trying to stuff an 8-character string into a local variable that is varchar(3). It's too long, so it causes an error when we call the function with that argument:

    ERROR 1406 (22001): Data too long for column 'v' at row 1
    

    Does this roll back the INSERT done during the same transaction? The proof would be when we SELECT after committing the transaction.

    Result:

    select * from t;
    +----+------+
    | id | word |
    +----+------+
    |  1 | bird |
    +----+------+
    

    The INSERT was not rolled back. Only the single statement that called the function with the error was rolled back ("rolling back" a SELECT has no observable effect).

    P.S.: This kind of quick proof of concept test is something you should be able to do yourself as a programmer. I think that's what the comments from RiggsFolly above were getting at.