¿Puede un incremento automático de identificación cambiar nunca del valor medio de transacción con motivo de comprometerse?

StackOverflow https://stackoverflow.com/questions/4682242

Pregunta

La posibilidad de que esto ocurra parece muy poco probable para mí, porque de los problemas que podría causar, pero pensé que le pediría la pregunta de todos modos ...

Imagine una transacción en la que un ID de incremento automático está implicado y se le asigna un valor. Antes de COMMIT, el código involucrado almacena una copia del ID asignado para su posterior consulta. A continuación, se confirma la transacción.

Si se asume ninguna intervención directa del cliente (supresión o alteración del registro), ¿hay alguna base de datos o situación que pueda alterar nunca automáticamente el valor de la identificación inmediatamente después de COMMIT, haciendo que el ID almacenado en caché incorrecto? ¿Es siempre seguro para guardar el ID del mediados de transacción?

Un caso hipotético de que me puedo imaginar que esto ocurra es si alguna aplicación RDBMS decidió inexplicablemente era necesario tener valores autoincrement sin espacios en blanco y dependientes del tiempo (ya que veo muchos ejemplos de personas que quieren este). En este caso hipotético, puedo imaginar algunos barajado mágico de IDs se podría hacer para llenar los vacíos causados ??por rollbacks post-ID-asignación en otra transacción (u otro causante hueco). Esto invalidaría el valor almacenado en caché.

Alguien sabe de este tipo de implementación, u otro asesino en caché?

¿Fue útil?

Solución

La aplicación de los valores de ID generado por lo general implica incrementar un valor del contador en una operación atómica corto. Este valor se utiliza para la transacción solicitando e incluso si esa transacción sería retroceder, el valor reservado nunca será devuelta a la piscina de los valores libres. Así que en este punto de vista no creo que la situación descrita es muy probable. Además, en PL / SQL tipo de programas que realmente necesita el valor generado a estar bien con el fin de insertar otros filas dependientes de tablas secundarias.

En cuanto a las personas que están queriendo valores sin pausas id ordenados por tiempo: el único propósito de clave de incremento automático / sustituta es crear una identificación artificial para una fila. Se debería tener nada que ver con la determinación del orden en el que fueron creados filas. Hay mucho mejores maneras de hacer esto, por ejemplo usando una marca de tiempo de creación.

Otros consejos

soportes PostgreSQL DEFERRED desencadenantes que pueden alterar los datos sobre 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;

La primera SELECT (justo antes de la COMMIT) 1 rendimientos, la segunda (a la derecha después de la COMMIT) devuelve 11.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top