dverite a écrit 2 commentaires

  • [^] # Re: not exists

    Posté par  . En réponse au journal UPSERT dans PostgreSQL ça déchire. Évalué à 2.

    Justement les problèmes avec une transaction concurrente sont gérés par INSERT.. ON CONFLICT y compris dans le niveau d'isolation le plus faible, READ COMMITTED (qui est celui par défaut, donc forcément beaucoup de gens l'utilisent), c'est ce qui contribue beaucoup à son intérêt, comme le dit le billet.

    Il n'y a jamais de "dirty read" dans PostgreSQL, mais ça n'empêche pas le moteur lui-même de savoir, en présence d'une contrainte d'unicité, qu'une transaction veut insérer la même valeur qu'une autre qui n'a pas encore committé mais dont l'INSERT est déjà passé avec succès. Dans ce cas le deuxième INSERT est mis en attente du résultat de l'autre transaction. Si la première transaction fait un COMMIT, la deuxième partira une erreur de violation de clef unique. Si au contraire la 1ere transaction fait un ROLLBACK, la 2eme pourra continuer.

    C'est ce que je voulais dire par "l'UPSERT via INSERT…ON CONFLICT peut voir les changements d'une transaction concurrente". Ce n'est pas un dirty read (ni un phantom read qui est encore autre chose, cf https://en.wikipedia.org/wiki/Isolation_(database_systems)#Phantom_reads) parce que cette visibilité est interne à l'exécution de UPSERT.

    Il y a plein de détails à ce sujet sur le wiki PostgreSQL écrits au moment du développement de cette fonctionnalité, y compris des comparaisons avec les solutions d'autres SGBDs:

    https://wiki.postgresql.org/wiki/UPSERT

  • [^] # Re: not exists

    Posté par  . En réponse au journal UPSERT dans PostgreSQL ça déchire. Évalué à 3.

    Cette requête INSERT ne peut pas mettre à jour des lignes existantes, seulement insérer de nouvelles lignes, contrairement à un UPSERT qui oriente chaque nouvelle ligne vers un UPDATE ou un INSERT en fonction de l'existant.

    Par ailleurs cette clause NOT EXISTS(…) ne peut pas voir les changement d'une transaction concurrente qui n'aurait pas encore fait de COMMIT, alors que l'UPSERT via INSERT…ON CONFLICT peut le faire.