PHP / SQL et la commande LOCK TABLES

WRInaute discret
Bonjour à tous, Bonjour à toutes :)

J'ai une table "mailing" sur laquelle j'enregistre tous les emails à envoyer à mes membres.

Ainsi, cela me permet de ne pas surcharger le serveur en envoyer les emails instantanément grâce à la fonction mail() de PHP.

J'enregistre donc : le titre du message, l'expéditeur, le destinataire, le contenu de l'email et sa priorité (de 1 à 100)).

Puis une tâche CRON tourne régulièrement pour expédier un petit lot d'emails (max : 50 mails par session).

Seulement voilà, mon hébergeur limite les envois d'emails à 1000 par heure, par compte.

De ce fait, j'ai donc créé dix sous domaines (sous 10 utilisateurs différents) de type mailing1.monsite.com, mailing2.monsite.com, etc. Et sur chaque sous-domaine, j'ai inséré la fameuse tâche cron.

Mais mon problème est le suivant :

Les tâches se lancent régulièrement en même temps et de ce fait, certains emails s'expédient en plusieurs fois...

La première tâche cron se lance et expédie 50 emails (par ordre de priorité), mais comme la seconde se lance en même temps, elle a également le temps de lire et expédier les 50 emails (les mêmes que la première tâche...).

J'ai donc pensé à utiliser la fonction LOCK TABLES de MySQL.

Procédure de la tâche cron :
1) Je bloque l'accès en lecture, écriture et édition (SELECT, INSERT, UPDATE) ;
2) Je sélectionne 50 emails (par priorité) ;
3) Je les envoie ;
4) Je les supprime de la table "mailing" ;
5) Je déverouille la table.

Simplement, c'est la première fois que j'utilise cette commande SQL, une âme charitable peut-elle m'aiguiller sur son utilisation ?

Actuellement mon script est le suivant :

1) SELECT id, titre, message FROM mailing ORDER BY priorite ASC LIMIT 50;
2) Expédition des e-mails
3) DELETE FROM mailing WHERE id=55 OR id=56 OR id=117;

Merci par avance ! :)
 
WRInaute impliqué
Une autre approche pourrait être de faire un script CRON qui charge les autres scripts (des différents sous-domaines donc) les uns à la suite des autres
 
WRInaute discret
Ce n'est pas bête !!

Et tu vois, je n'y avais même pas pensé... Comme quoi les forums servent réellement à quelque chose ;)

En fait, j'enregistre les emails dans "mailing", et une tâche cron se charge de les enregistrer sur les différents sous-domaines (un sous domaine = une nouvelle BDD), ainsi plus de problèmes ! :D

Merciiiiiiiiiiiii ! ;)
 
WRInaute occasionnel
Je pense que @seebz parlait plus de lancement en asynchrone, c'est à dire, un cron pour les gouverner tous (merci la référence pourrie, mais ça me brulait la langue).

En fait, tu crée un nouveau CRON, qui lancera en asynchrone les autres CRONS, de cette manière :

file_get_content (script.php);
file_get_content (script_2.php);
file_get_content (script_3.php);

Ou un truc dans ce genre (il me semble que c'est la bonne syntaxe)

En fait file_get_content va exécuter script.php, et tant qu'il n'aura pas fini son exécution, il ne passera pas à la suite du code...
Du coup, chacun se fait à la queue-leuleu.....

Marche aussi avec les boucles de type while, for ,etc. :mrgreen:
Voilà
 
WRInaute impliqué
Le file_get_content utilisé de cette façon va plutôt récupérer le contenu du fichier.

Je veux juste réagir sur le LOCK TABLE.
Un verrou doit être déverrouillé le plus rapidement possible. Dans ton cas, ton processus aurait du être :
1) Je bloque l'accès en lecture, écriture et édition (SELECT, INSERT, UPDATE) ;
2) Je sélectionne 50 emails (par priorité) ;
3) Je les supprime de la table "mailing" ;
4) Je déverouille la table
5) Je les envoie ;.

Puisque l'étape de l'envoi peut prendre un temps plus ou moins long, il est préférable de déverrouiller avant.

Sinon, il est effectivement plus judicieux d'utiliser la méthode de seebz.
 
WRInaute discret
Merci pour votre aide ;)

Les emails sont tous stockés sur la même base,
Mais j'ai lancé plusieurs serveurs pour les expéditions, et les scripts sont appelés l'un après l'autre :)
 
Discussions similaires
Haut