The answer is triggers are not safe.
It turns out that the trigger really doesn't see uncommited changes done in other transactions and passes without an error. It can be demonstrated like this
Transaction 1:
START TRANSACTION;
INSERT INTO plays_in (BetID, PlayerID) VALUES (1,1); -- query A
Transaction 2:
START TRANSACTION;
INSERT INTO plays_in (BetID, PlayerID) VALUES (1,2); -- query B; in conflict with A, but passses
Both transactions:
COMMIT;
Now plays_in
will contains both inserted records even though if A and B were executed in a single transaction, the trigger would throw an error.
The whole example sources can be obained here
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…