在MySQL中,如何在更新触发器后回滚更新?

3
我正在使用mysql 5.1.72-0ubuntu0.10.04.1 (Ubuntu)。我想创建一个触发器,以防止玩家和墙之间的碰撞。
玩家和墙表都有x和y列。
我有以下触发器:
CREATE TRIGGER checkcollision AFTER UPDATE ON players BEGIN 
    SELECT RAISE(ABORT, 'collision') FROM walls WHERE NEW.x=x AND NEW.y=y; 
END;

我想知道如果有任何实际选择的行,这个触发器是否会回滚更新,考虑到我的mysql版本。还是我必须手动回滚?

此外,我的触发器存在语法问题,我不确定是什么问题。

有人知道吗?

编辑:

我认为我需要从这里获取旧的语法:https://dev.mysql.com/doc/refman/5.0/en/commit.html

但我不知道如何完成代码...

START TRANSACTION;
SELECT p.* FROM players p WHERE EXISTS (SELECT w.* FROM walls w WHERE w.x=p.x AND w.y=p.y);
COMMIT;
ROLLBACK;

编辑2:

出现语法错误:

DELIMITER // 
CREATE TRIGGER checkcollision AFTER UPDATE ON players 
    FOR EACH ROW 
    BEGIN 
        IF (SELECT count(*) FROM walls WHERE NEW.x=x AND NEW.y=y)>0 THEN 
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Collision detected'; 
        END IF; 
    END;// 
DELIMITER ; 
1个回答

1
根据文档,内容如下:

According the documentation

当触发器被激活时,其执行语句存在以下限制:

  • 触发器不能使用明确或隐含地开始或结束事务的语句,例如START TRANSACTION、COMMIT或ROLLBACK。(ROLLBACK to SAVEPOINT是允许的,因为它不会结束事务。)

MySQL在触发器执行期间处理错误的方式如下:

  • 如果BEFORE触发器失败,则不会执行对应行上的操作。

  • 无论尝试插入或修改行是否成功,BEFORE触发器都会被激活。

  • 只有在所有BEFORE触发器和行操作成功执行后,才会执行AFTER触发器。

  • BEFORE或AFTER触发器中的任何错误都会导致触发器调用所引起的整个语句失败。

  • 对于事务表,语句失败应导致该语句执行的所有更改回滚。触发器失败会导致语句失败,因此触发器失败也会导致回滚。对于非事务表,这种回滚无法进行,因此尽管语句失败,但在错误点之前执行的任何更改仍然有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接