Problème de concurrence avec UPDATE...SELECT sous forte charge
Problème de concurrence avec UPDATE...SELECT sous forte charge
Sur notre appli e-commerce, on a des deadlocks quand plusieurs clients commandent le même produit rare. La requête 'UPDATE stock SET qty=qty-1 WHERE product_id=X AND qty>0' bloque tout. Solutions ?
-
sebastien75
- Messages : 37
- Inscription : jeu. avr. 18, 2024 7:24 pm
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
Classique ! Il faut isoler ta transaction en SERIALIZABLE ou utiliser SELECT FOR UPDATE. Mais attention aux perf.
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
J'éviterais SERIALIZABLE, trop lourd. Opte plutôt pour des retries exponentiels avec backoff. Chez nous on utilise ce pattern avec un max_retries=3 et ça résout 99% des cas.
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
Solution radicale : passe en optimistic locking. Ajoute un version_id que tu vérifies dans ton UPDATE. Moins de blocages mais besoin de gérer les échecs côté applicatif.
Ex-Windows, jamais regrette le switch
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
Le SELECT FOR UPDATE marche bien mais ça ralentit tout quand il y a >100 req/s. Je vais tester le optimistic locking + retry. Vous avez un exemple concret en PostgreSQL ?
-
sebastien75
- Messages : 37
- Inscription : jeu. avr. 18, 2024 7:24 pm
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
Pour PostgreSQL spécifiquement, regarde du côté des SKIP LOCKED. C'est parfait pour les files d'attente. Exemple : UPDATE ... WHERE id IN (SELECT id FROM stock WHERE ... FOR UPDATE SKIP LOCKED LIMIT 10)
Re: Problème de concurrence avec UPDATE...SELECT sous forte charge
N'oubliez pas de vérifier vos timeouts (lock_timeout, statement_timeout). J'ai déjà vu des deadlocks qui duraient 30s par défaut...