Может ли идентификатор автоинсюрмана когда-либо измениться от среднего значения транзакции при совершении коммита?

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

Вопрос

Возможность этого кажется мне чрезвычайно маловероятным из -за проблем, которые это может вызвать, но я подумал, что все равно задаю вопрос ...

Представьте себе транзакцию, в которой участвует идентификатор автоинскручения и назначается значение. До совершения задействованного кода кэширует копия назначенного идентификатора для последующей ссылки. Тогда транзакция совершена.

Предполагая, что нет прямого вмешательства клиента (удаление или изменение записи), есть ли какая -либо база данных или ситуация, которая когда -либо автоматически изменяет значение идентификатора сразу после совершения, делая кэшированный идентификатор неправильным? Всегда ли безопасно кэшировать ID в середине транзакции?

Один гипотетический случай, когда я могу себе представить, что это происходит, если какая-то реализация RDBMS необъяснимо решила, что необходимо иметь значения автостоинкремента без пробела и зависимых от времени (поскольку я вижу много примеров людей, желающих этого). В этом гипотетическом случае я могу представить себе, как может быть сделано некоторые магические перетасовки идентификаторов, чтобы заполнить пробелы, вызванные откатами в ассигновании после ID в другой транзакции (или другой причине пробела). Это лишает недействительного кэшированного значения.

Кто -нибудь знает о такой реализации или другой убийце кеша?

Это было полезно?

Решение

Реализация сгенерированных значений ID обычно включает увеличение значения счетчика в короткой атомной операции. Это значение затем используется для запрашивающей транзакции, и даже если эта транзакция откатится назад, зарезервированное значение никогда не будет возвращено в пул свободных значений. Так что в этом свете я не думаю, что описанная ситуация очень вероятно. Кроме того, в программах типа PL/SQL вам действительно нужно, чтобы сгенерированное значение было правильным, чтобы вставить другие зависимые строки в детские таблицы.

Что касается людей, которые хотят, чтобы идентификационные значения без разрыв: единственная цель автоинскрущения/суррогатного ключа-создать искусственную идентификацию для ряда. Это не должно иметь ничего общего с определением порядка, в котором были созданы строки. Есть гораздо лучшие способы сделать это, например, с использованием временной метки создания.

Другие советы

PostgreSQL поддержка DEFERRED триггеры, которые могут изменить данные на 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;

Первый SELECT (Прямо перед COMMIT) возврат 1, второй (сразу после COMMIT) возврат 11.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top