and without creating a table to pass the state around (really just an excuse to use the named locks feature).
DELIMITER //
DROP FUNCTION IF EXISTS SET_BREAKPOINT//
CREATE FUNCTION SET_BREAKPOINT()
RETURNS tinyint
NO SQL
BEGIN
-- Acquire lock 1
-- Wait until lock 2 is taken to signal that we may continue
DO GET_LOCK(CONCAT('lock_1_', CONNECTION_ID()), -1);
REPEAT
DO 1;
UNTIL IS_USED_LOCK(CONCAT('lock_2_', CONNECTION_ID())) END REPEAT;
DO RELEASE_LOCK(CONCAT('lock_1_', CONNECTION_ID()));
-- Acquire lock 3 to acknowledge message to continue.
-- Wait for lock 2 to be released as signal of receipt.
DO GET_LOCK(CONCAT('lock_3_', CONNECTION_ID()), -1);
REPEAT
DO 1;
UNTIL IS_FREE_LOCK(CONCAT('lock_2_', CONNECTION_ID())) END REPEAT;
DO RELEASE_LOCK(CONCAT('lock_3_', CONNECTION_ID()));
RETURN 1;
END//
DROP FUNCTION IF EXISTS …[Read more]