Est-il possible de libérer automatiquement un verrou dans PostgreSQL?
-
19-09-2019 - |
Question
Je teste la tolérance aux pannes d'un système ActiveMQ configuré comme JDBC maître / esclave. Dans cette configuration, il y a une base de données Postgres et deux courtiers - l'un est le courtier maître, l'autre est un courtier esclave. La façon dont ce mécanisme fonctionne est le maître prend un verrou exclusif sur une table dans la db. L'esclave essaie de le faire aussi et attend jusqu'à ce que le verrou devient disponible. Si le maître meurt, le verrou doit être libéré et l'esclave prendra le relais. Cependant, si le maître perd la connectivité réseau avec la base de données, le verrou est jamais sorti résultant dans un scénario de blocage. Ce qui semble être nécessaire ici est une façon de dire Postgres pour libérer automatiquement le verrou si pas renouvelé dans un délai de temps. Le livre POSA 3 des modèles de conception appelle cela le modèle de location. Est-il possible d'obtenir Postgres pour ce faire? Dans le cas contraire, ne les autres fournisseurs de bases de données soutiennent?
La solution
Ce n'est pas une impasse, cela est un problème de connexion perdue.
Un blocage se produit lorsque deux transactions tentent de verrouiller les ressources précédemment bloquées par l'autre. PostgreSQL
détecte ces situations.
Dans votre cas, master
verrouille une ressource, attend slave
pour master
, et attend master
pour l'entrée utilisateur qu'il reçoit jamais parce que la connexion est perdue.
Chaque fois que PostgreSQL
détecte une perte de connexion, il rollbacks sa transaction automatiquement.
Pour contrôler la détection de perte de connexion, vous pouvez utiliser le PostgreSQL
suivant options de connexion :
tcp_keepalives_idle (integer)
Sur les systèmes qui prennent en charge l'option prise
TCP_KEEPIDLE
, indique le nombre de secondes entre l'envoi keepalives sur une connexion autrement ralenti. Une valeur de zéro utilise la valeur par défaut du système. SiTCP_KEEPIDLE
n'est pas pris en charge, ce paramètre doit être zéro. Ce paramètre est ignoré pour les connexions via un socket de domaine Unix.
tcp_keepalives_interval (integer)
Sur les systèmes qui prennent en charge l'option prise
TCP_KEEPINTVL
, indique combien de temps, en secondes, d'attendre une réponse à un keepalive avant retransmettant. Une valeur de zéro utilise la valeur par défaut du système. SiTCP_KEEPINTVL
n'est pas pris en charge, ce paramètre doit être zéro. Ce paramètre est ignoré pour les connexions via un socket de domaine Unix.
tcp_keepalives_count (integer)
Sur les systèmes qui prennent en charge l'option prise
TCP_KEEPCNT
, indique le nombre de keepalives peut être perdu avant que la connexion est considérée comme morte. Une valeur de zéro utilise la valeur par défaut du système. SiTCP_KEEPCNT
n'est pas pris en charge, ce paramètre doit être zéro. Ce paramètre est ignoré pour les connexions via un socket de domaine Unix.