Oyun Kitabı
Base de données prise en charge fonctionne avec location (Base DE Donnees Prise EN Charge Fonctionne Avec Location)
Location avec MISE À JOUR Conditionnelle, un observateur qui enregistre les tâches bloquées et pourquoi le simple fait de supprimer le message ne suffit pas à payer la production.
Moteur de paiement distribué
Partie 13 de 22
Une série d'architectures de paiement distribuées qui comblent le fossé entre la capture et l'achèvement.
Nous avons établi l'algorithme de nouvelle tentative dans la section précédente ; mais cet algorithme supposait par quel travailleur un travail était exécuté. Si plusieurs travailleurs sont extraits de la même file d'attente, la même tâche de paiement peut-elle être traitée par deux travailleurs en même temps ?
Les courtiers de messages résolvent ce problème avec « délai d'attente de visibilité » ou « ack/nack ». Mais dans une file d'attente de tâches basée sur une base de données (l'approche privilégiée dans de nombreux systèmes de paiement, car l'état de la tâche réside déjà dans la base de données), la même garantie est fournie via le modèle location.```text Worker A Worker B │ SELECT ... FOR UPDATE? │ │ ya da conditional UPDATE │ ▼ ▼ Job'ı kilitlemeye çalışır Job'ı kilitlemeye çalışır → sadece biri kazanır
## Concepts à la première mention```text
📦 Lease
Bir worker'ın bir işi belirli bir süre için 'sahiplendiğini' işaretleyen zaman damgalı kayıt.
📦 Conditional UPDATE
Sadece beklenen koşul (örn. status = Pending) doğruysa satırı güncelleyen atomik SQL işlemi.
📦 Lease süresi (Lease TTL)
Bir worker'ın işi ne kadar süreyle sahiplenebileceğinin üst sınırı; bu süre geçince iş tekrar alınabilir hale gelir.
📦 Stuck Watcher
Lease'i süresi dolmuş ama tamamlanmamış işleri periyodik olarak tarayıp yeniden kuyruğa alan arka plan süreci.
```Le bail n’est pas un verrou ; Si le processus détenant le verrou plante, le verrou peut rester indéfiniment. Étant donné que le bail a une durée, même si le travailleur tombe en panne, le travail est automatiquement libéré après un certain temps.
## Moyen atomique d'obtenir un bail
La lecture puis la mise à jour (lecture puis écriture) pour récupérer un travail sont sujettes à une situation de concurrence critique : deux travailleurs peuvent lire la même ligne, tous deux voient "vide", tous deux tentent de mettre à jour. La bonne méthode consiste à déplacer la lecture et la condition dans la même expression atomique :```sql
UPDATE payment_jobs
SET status = 'Processing',
lease_owner = :workerId,
lease_until = now() + interval '60 seconds'
WHERE id = :jobId
AND (status = 'Pending' OR (status = 'Processing' AND lease_until < now()))
RETURNING id;
```Si cette MISE À JOUR ne renvoie aucune ligne, le travail est déjà sur un autre travailleur ou toujours sous un bail valide — le travailleur passe silencieusement au travail suivant. Si la ligne est renvoyée, ce travailleur est désormais le seul propriétaire du travail ; jusqu'à l'expiration du bail.
## Pourquoi la durée du bail devrait-elle être prolongée avec un battement de cœur ?
Une durée de location fixe (par exemple 60 secondes) peut ne pas suffire pour chaque transaction. Une opération qui peut prendre beaucoup de temps (par exemple, un appel PSP devient inopinément long) doit être prolongée avec pulsation avant l'expiration du bail :```text
Worker işe başlar → lease_until = now + 60s
... iş sürüyor ...
Worker heartbeat gönderir → lease_until = now + 60s (yenilenir)
... iş tamamlanır ...
Worker status = Completed olarak işaretler
```Un travailleur qui ne peut pas envoyer de battement de cœur (en panne, déconnecté du réseau) ne peut pas renouveler le bail ; le délai expire et le travail redevient disponible. Il s'agit du mécanisme qui garantit que le scénario de crash est géré automatiquement.
## Stuck watcher : qui détecte les emplois avec des baux expirés
Le travail n'est pas automatiquement « récupéré » à l'expiration du bail : un travailleur doit le `SELECT` à nouveau. Ainsi, un processus d'observation exécuté périodiquement recherche les tâches dont le bail a expiré mais sont toujours dans l'état `Processing` et les rend récupérables (ou les affecte directement à un nouveau travailleur).```text
Watcher (her 30 saniyede bir)
SELECT id FROM payment_jobs
WHERE status = 'Processing' AND lease_until < now()
→ bu işler 'stuck' olarak işaretlenir veya doğrudan Pending'e döndürülür
```Sans Watcher, le travail laissé par un travailleur en panne peut sembler être un « traitement » pour toujours ; Un paiement n’est jamais effectué sans que personne ne s’en aperçoive.
## Pourquoi le Nack du courtier seul ne suffit pas
Si un travailleur sur un courtier de messages `Nack` le message (ou le délai d'expiration de la visibilité expire), le message retourne dans la file d'attente. Ceci est très similaire à un bail dans une base de données — mais deux différences importantes sont importantes : premièrement, la propre fenêtre de visibilité du courtier est souvent désynchronisée avec l'enregistrement persistant de l'état de votre entreprise (le message peut être perdu ou être livré deux fois) ; Deuxièmement, `Nack` dit simplement « laisser ce message », ne sachant en permanence *à quel stade* le travail est bloqué ni combien de fois il a été essayé. Le bail basé sur une base de données maintient le statut des tâches et l'historique des essais dans la même limite de transaction, interrogeable.
## Distinctions souvent confuses```text
❌ Lease = kilit (lock)
✓ Lease süresi dolan bir zaman sınırıdır; kilit process çökerse sonsuza kalabilir
❌ Read-then-write yeterlidir
✓ Read-then-write yarış durumuna açıktır; conditional UPDATE atomik olmalıdır
❌ Nack, lease'in yerini tamamen tutar
✓ Nack mesaj görünürlüğünü yönetir; lease iş durumunu ve deneme geçmişini kalıcı olarak tutar
```## Comparaison du bail soutenu par la base de données et du délai d'expiration de la visibilité du courtier
| Critère | Délai d'expiration de la visibilité du courtier | Bail adossé à la DB |
| --- | --- | --- |
| Questionnement du statut | Limité | Complet avec SQL |
| Persistance de l'historique des essais | Dépend du courtier | Facilement sur la même ligne |
| Détection d'un travail bloqué | Indirect | Avec requête directe |
## Liste de contrôle lors de la conception d'un bail
1. Le bail est-il une seule instruction atomique `UPDATE ... WHERE` ou une instruction en lecture puis écriture ?
2. La durée du bail est-elle réellement plus longue que le délai de traitement prévu le plus long ?
3. Existe-t-il un renouvellement de bail avec battement de cœur pour les transactions qui peuvent prendre beaucoup de temps ?
4. L'observateur Stuck fonctionne-t-il périodiquement ou les tâches dont le bail a expiré restent-elles « en cours de traitement » pour toujours ?
5. Le champ `lease_owner` stocke-t-il à des fins de diagnostic quelle instance de travail a reçu la tâche ?
6. Le nombre d'essais est-il augmenté à chaque location et conservé en permanence ?
## Ce qu'il faut retenir de cet article
1. Le bail n’est pas un verrou ; Il s'agit d'un droit de propriété limité dans le temps et qui prend fin automatiquement.
2. L'obtention d'un bail nécessite une MISE À JOUR conditionnelle atomique ; la lecture puis l'écriture est sujette à des conditions de concurrence.
3. Les transactions longues doivent renouveler le bail en un clin d'œil ; Dans le cas contraire, le bail pourrait prendre fin de manière anticipée.
4. Stuck Watcher est un processus d'arrière-plan obligatoire qui récupère les tâches laissées par les travailleurs en panne.
> La fiabilité d'une file d'attente de tâches n'est pas sur la bonne voie ; Il est testé lorsqu'un travailleur s'écrase au milieu.
Dans la section suivante, nous examinons un type de travailleur qui s'appuie sur ce mécanisme de location : le travailleur de réconciliation, qui fonctionne avec succès sur PSP mais améliore les paiements toujours en attente dans le système.
FAQ
Frequently asked questions
Qu'est-ce qu'un bail ?
Un enregistrement horodaté qui indique qu'un travailleur « possède » un emploi pendant une période de temps spécifique.
Qu’est-ce que la MISE À JOUR conditionnelle ?
Opération SQL atomique qui met à jour la ligne uniquement si la condition attendue (par exemple, status = Pending) est vraie.
"Lease = lock (lock)" est-il correct ?
Un bail est un délai qui expire ; Le verrou peut persister pour toujours si le processus plante
Que corrige cette section ?
Les courtiers de messages résolvent ce problème avec « délai d'attente de visibilité » ou « ack/nack ». Mais dans une file d'attente de tâches basée sur une base de données (l'approche privilégiée dans de nombreux systèmes de paiement, car l'état de la tâche réside déjà dans la base de données), la même garantie est fournie via le modèle **location**. Le bail n’est pas un verrou ; Il s'agit d'un droit de propriété limité dans le temps et qui prend fin automatiquement. Nous avons établi l'algorithme de nouvelle tentative dans la section précédente ; mais cet algorithme supposait *par quel travailleur* un travail était exécuté. Si plusieurs travailleurs sont extraits de la même file d'attente, la même tâche de paiement peut-elle être traitée par deux travailleurs en même temps ?
Principes d'ingénierie appris
- Le bail n’est pas un verrou ; Elle est limitée dans le temps et se termine automatiquement.
- L’obtention d’un bail nécessite une MISE À JOUR conditionnelle atomique, et non une lecture puis une écriture.
- Sans un observateur coincé, l'emploi du travailleur accidenté pourrait être perdu à jamais.
Continuer la lecture
Continuer la lecture
Suivant en série
Travailleur au rapprochement des paiements dans la construction
Comment les balayeuses améliorent la dérive : Même si le PSP réussit, l'enregistrement local peut être expiré ; Comment récupérer un FinalizePending ancien.…
Suivant en série
Algorithmes de nouvelle tentative pour les agents de paiement
Interruption exponentielle, gigue, plafond, différence de report ou de nouvelle tentative et disjoncteur : traduisez la taxonomie de la section précédente…
Même série
Payé mais pas de commande : amélioration
Guide de réponse aux incidents : client facturé mais aucune commande passée ; encombrement multi-intentionnel du panier ; Nettoyer soigneusement la…