Question

La possibilité que cela se produise me semble très peu probable en raison des problèmes qu'elle pourrait causer, mais je me suis dit que je pose la question de toute façon ...

Imaginez une transaction où un ID autoincrement est impliqué et une valeur est affectée. Avant COMMIT, le code impliqué met en cache une copie de l'ID attribué pour référence ultérieure. Ensuite, la transaction est validée.

En supposant aucune intervention directe du client (suppression ou modification de l'enregistrement), est-il une base de données ou d'une situation qui jamais modifier automatiquement la valeur d'identification immédiatement après COMMIT, ce qui rend l'ID cache incorrect? Est-il toujours sûr de mettre en cache la mi-transaction ID?

Un cas hypothétique où je peux imaginer ce qui se passe est si une mise en œuvre de SGBDR inexplicablement décidé qu'il était nécessaire d'avoir des valeurs et gapless d'auto-incrémentation en fonction du temps (depuis que je vois beaucoup d'exemples de personnes qui veulent cela). Dans ce cas hypothétique, je peux imaginer un certain brassage magique des ID peut être fait pour combler les lacunes causées par rollbacks post-ID-affectation dans une autre transaction (ou tout autre écart Causer). Cela annule la valeur mise en cache.

Quelqu'un sait d'une telle mise en œuvre, ou un autre tueur cache?

Était-ce utile?

La solution

La mise en oeuvre des valeurs d'identifiant généré implique généralement incrémenter une valeur de compteur dans une courte opération atomique. Cette valeur est ensuite utilisée par la transaction demande et même si cette opération annuler, la valeur réservée ne sera jamais rendu à la piscine des valeurs libres. Donc, dans cette lumière, je ne pense pas que la situation décrite est très probable. En outre, dans pl / sql type de programmes que vous avez vraiment besoin de la valeur générée pour être droit afin d'insérer d'autres lignes dépendantes aux tables de l'enfant.

En ce qui concerne les personnes qui manquent des valeurs id gapless ordonnées dans le temps: le seul but de clé autoincrement / de remplacement est de créer une identification artificielle pour une ligne. Il devrait avoir rien à voir avec la détermination de l'ordre dans lequel les lignes ont été créées. Il y a de bien meilleures façons de le faire, par exemple en utilisant un horodatage de création.

Autres conseils

supports PostgreSQL DEFERRED déclencheurs qui peuvent modifier les données sur COMMIT.

CREATE TABLE test_autoinc (id BIGSERIAL);

CREATE TABLE test_other (id BIGSERIAL);

CREATE FUNCTION prc_update_autoinc()
RETURNS TRIGGER
AS
$$
BEGIN
        UPDATE  test_autoinc
        SET     id = id + 10;
        RETURN  NEW;
END;
$$
LANGUAGE 'plpgsql';

CREATE CONSTRAINT TRIGGER
        trg_other_ai
AFTER INSERT
ON      test_other
DEFERRABLE
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE prc_update_autoinc();

BEGIN TRANSACTION;

INSERT
INTO    test_autoinc
DEFAULT VALUES;

INSERT
INTO    test_other
DEFAULT VALUES;

SELECT  *
FROM    test_autoinc;

COMMIT;

SELECT  *
FROM    test_autoinc;

Le premier SELECT (juste avant la COMMIT) 1 rendements, le second (à droite après le COMMIT) renvoie 11.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top