提交时,自动增量ID是否可以从中间事务值更改?

时间:2011-01-13 16:10:39

标签: sql transactions commit auto-increment rdbms-agnostic

发生这种情况的可能性对我来说似乎不太可能,因为它可能导致问题,但我想我还是会问这个问题......

想象一下涉及自动增量ID并分配值的事务。在COMMIT之前,涉及的代码缓存分配的ID的副本供以后参考。然后提交交易。

假设没有直接的客户端干预(删除或更改记录),是否有任何数据库或情况会在COMMIT后立即自动更改ID值,使缓存的ID不正确?在交易中间缓存ID是否总是安全的?

我可以想象这种情况发生的一个假设情况是,如果某些RDBMS实现莫名其妙地决定必须具有无间隙和时间依赖的自动增量值(因为我看到许多人想要这样做的例子)。在这个假设的情况下,我可以想象可能会进行一些神奇的ID改组以填补由另一个事务(或其他间隙记录器)中的ID后分配回滚引起的间隙。这会使缓存的值无效。

任何人都知道这样的实现或其他缓存杀手?

2 个答案:

答案 0 :(得分:4)

生成的id值的实现通常涉及在短原子操作中递增计数器值。然后,该值将由请求事务使用,即使该事务将回滚,保留值也永远不会返回给可用值池。所以从这个角度来看,我不认为所描述的情况很有可能。此外,在pl / sql类型的程序中,您确实需要生成的值才能将其他相关行插入子表。

对于想要按时间排序的无间隙id值的人:自动增量/代理键的唯一目的是为行创建人工识别。它与确定行的创建顺序无关。有更好的方法可以做到这一点,例如使用创建时间戳。

答案 1 :(得分:1)

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