2011-04-29 5 views
2

Je commence à utiliser des triggers dans MySQL, et j'ai un problème. J'ai écrit des Triggers qui vont mettre à jour ma table users et faire des notifications = notifications + 1 (à un utilisateur) quand j'insère quelque chose dans la table des notifications. Cela semble fonctionner, mais j'ai fait un 'check-cron-script', qui s'exécute toutes les minutes, et met à jour la table des utilisateurs avec 100% de vraies valeurs qui devraient être là (compter à partir de la table des notifications). Ce cron m'envoie un email s'il met à jour certaines lignes. Si ce script apporte des modifications, il m'enverra un email contenant le user_id qui a une mauvaise valeur. Il y a quelque temps, j'ai reçu deux courriels d'affilée (22:53, 22:54) me disant que le script trouvait une mauvaise valeur dans la table des utilisateurs, et qu'il fallait mettre à jour 1 ligne. Les deux emails étaient les mêmes (même utilisateur, même chose). Et je me demande maintenant ce qui est arrivé.MySQL Trigger Problème

UPDATE query: 
INSERT INTO notifications (user_id,title,notification) VALUES (%i,%s,%s) 

AFTER INSERT TRIGGER: 
BEGIN 
IF NEW.`new` > 0 THEN 
UPDATE users SET notifications=notifications+1 WHERE id=NEW.user_id; 
END IF; 
END 

AFTER UPDATE TRIGGER: 
BEGIN 
IF OLD.`new` != NEW.`new` THEN 
IF OLD.`new` > 0 THEN 
UPDATE users SET notifications=notifications-1 WHERE id=OLD.user_id; 
END IF; 
IF NEW.`new` > 0 THEN 
UPDATE users SET notifications=notifications+1 WHERE id=NEW.user_id; 
END IF; 
END IF; 
END 

AFTER DELETE TRIGGER: 
BEGIN 
IF OLD.`new` > 0 THEN 
UPDATE users SET notifications=notifications-1 WHERE id=OLD.user_id; 
END IF; 
END 

notifications.new est un tinyint qui indique si l'utilisateur de lire la notification allready (la valeur par défaut est 1)

Le tableau des notifications ne sont pas mis à jour si souvent, donc je pensais que devrait avoir arrivé, et la seule chose que je pense devrait arriver est: 1. La requête UPDATE a été exécutée 2. Le cron exécuté avant le déclencheur, et a dû changer la valeur, parce qu'il était faux 3. Le déclencheur a été exécuté 4 Lors de la prochaine exécution du cron, la valeur était supérieure à ce qu'elle devait être, donc le cron devait le mettre à jour à nouveau (même utilisateur, même chose, même courriel)

Mais je ne sais vraiment pas si une telle chose peut arriver. Si APRÈS DÉCLENCHEUR est un peu retardé, et si le cron peut être exécuté après la requête, mais avant le DÉCLENCHEUR.

Répondre

0

Les déclencheurs sont atomiques. Sauf si vous utilisez tx_isolation=READ-UNCOMMITTED, le scénario que vous avez décrit ne devrait pas être possible.

+0

Salut, j'ai regardé là et il est réglé sur REPEATABLE-READ. Donc ce n'est probablement pas possible. Et si vous regardez la requête et les déclencheurs, ne voyez-vous pas un autre problème qui devrait causer la chose que j'ai écrite? – Kukosk