En supposant:
J'ai les questions suivantes:
INSERT
provoque un blocage? Si oui, veuillez fournir un scénario détaillé montrant comment un blocage peut survenir (par exemple, le fil 1 fait ceci, le fil 2 fait cela, ..., un point mort).UPDATE: 3. Pour les points super bonus: comment puis-je éviter une impasse dans le scénario suivant?
Tableaux donnés:
[id BIGINT PRIMARY KEY]
[id BIGINT PRIMARY KEY, name VARCHAR(30), permission_id BIGINT NOT NULL, FOREIGN KEY (permission_id) REFERENCES permissions(id))
Je crée une nouvelle société comme suit:
Je supprime une entreprise comme suit:
Dans l'exemple ci-dessus, l'ordre de verrouillage INSERT est [autorisations, sociétés], tandis que l'ordre de verrouillage SUPPRIMER est [sociétés, autorisations]. Existe-t-il un moyen de corriger cet exemple pour l'isolement REPEATABLE_READ
ou SERIALIZABLE
?
En règle générale, toutes les modifications peuvent provoquer un blocage et la sélection ne le fera pas (y revenir plus tard). Alors
Vous n'avez même pas besoin de plusieurs tables.
La meilleure façon de créer une impasse est de faire la même chose dans un ordre différent.
Exemples SQL Server:
create table A
(
PK int primary key
)
Session 1:
begin transaction
insert into A values(1)
Session 2:
begin transaction
insert into A values(7)
Session 1:
delete from A where PK=7
Session 2:
delete from A where PK=1
Vous obtiendrez une impasse. Donc, cela prouvé inserts et supprime peut impasse.
Les mises à jour sont similaires:
Session 1:
begin transaction
insert into A values(1)
insert into A values(2)
commit
begin transaction
update A set PK=7 where PK=1
Session 2:
begin transaction
update A set pk=9 where pk=2
update A set pk=8 where pk=1
Session 1:
update A set pk=9 where pk=2
Impasse!
SELECT ne doit jamais se bloquer, mais sur certaines bases de données, cela se produira, car les verrous utilisés interfèrent avec des lectures cohérentes. C'est juste la conception de moteur de base de données merdique cependant.
SQL Server ne sera pas verrouillé sur un SELECT si vous utilisez SNAPSHOT ISOLATION. Oracle et moi-même pensons que Postgres ne se verrouillera jamais sur SELECT (sauf si vous avez FOR UPDATE qui réserve clairement une mise à jour de toute façon).
Donc, fondamentalement, je pense que vous avez quelques hypothèses incorrectes. Je pense avoir prouvé:
Vous devrez juste prendre mon mot sur SELECT;) mais cela dépendra de votre base de données et de vos paramètres.
En plus de la réponse de LoztInSpace, inserts
peut provoquer des blocages même sans présence de deletes
ou updates
Tout ce dont vous avez besoin est un index unique et un ordre d'opérations inversé.
Exemple dans Oracle:
create table t1 (id number);
create unique index t1_pk on t1 (id);
--thread 1 :
insert into t1 values(1);
--thread 2
insert into t1 values(2);
--thread 1 :
insert into t1 values(2);
--thread 2
insert into t1 values(1); -- deadlock !
Supposons que vous avez deux relations A
et B
et deux utilisateurs X
et Y
. La table A est WRITE verrouillée par l'utilisateur X et la table B est WRITE verrouillée par Y. La requête suivante vous donnera un verrou mort s'il est utilisé à la fois par les utilisateurs X et Y.
Select * from A,B
Il est donc clair qu'une opération Select
peut provoquer un blocage, si des opérations de jointure impliquant plusieurs tables en font partie. Les opérations d'insertion et de suppression impliquent généralement des relations uniques. Donc, ils ne peuvent pas provoquer une impasse.