Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 提交时,自动增量ID是否会从中间事务值更改?_Sql_Transactions_Commit_Auto Increment_Rdbms Agnostic - Fatal编程技术网

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

Sql 提交时,自动增量ID是否会从中间事务值更改?,sql,transactions,commit,auto-increment,rdbms-agnostic,Sql,Transactions,Commit,Auto Increment,Rdbms Agnostic,对我来说,发生这种情况的可能性似乎极不可能,因为它可能会导致一些问题,但我想我还是会问这个问题 想象一个事务,其中涉及一个自动增量ID并分配了一个值。在提交之前,所涉及的代码将缓存分配的ID的副本,以供以后参考。然后提交事务 假设没有直接的客户端干预(删除或更改记录),是否有任何数据库或情况会在提交后立即自动更改ID值,从而使缓存的ID不正确?在事务中缓存ID是否总是安全的? 我可以想象发生这种情况的一个假设情况是,如果某个RDBMS实现莫名其妙地决定有必要使用无间隙和时间相关的自动增量值(因为

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

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

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

我可以想象发生这种情况的一个假设情况是,如果某个RDBMS实现莫名其妙地决定有必要使用无间隙和时间相关的自动增量值(因为我看到很多人希望这样做)。在这个假设的情况下,我可以想象可能会进行一些神奇的ID洗牌,以填补另一个事务(或其他间隙原因)中ID分配后回滚所造成的间隙。这将使缓存的值无效


有人知道这样的实现或其他缓存杀手吗?

PostgreSQL
支持
延迟
触发器,可以更改
提交
上的数据

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
生成的id值的实现通常涉及在短原子操作中增加计数器值。然后,请求事务将使用该值,即使该事务将回滚,保留值也永远不会返回到自由值池。因此,从这个角度来看,我认为上述情况不太可能发生。此外,在pl/sql类型的程序中,为了将其他依赖行插入到子表中,确实需要生成正确的值


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

+1虽然我认为您使用自动编号是绝对正确的。。。从技术上讲,根据定义,如果您打算使用该值来确定创建顺序,则它们不再是代理键:DIn
InnoDB
,MySQL使用的事务存储引擎,可以重用自动递增ID。如果删除id最高的记录并重新启动服务器,则下一次插入表将导致相同的id。Thx。。。有趣的例子+1用于显示可能发生的情况,尽管有直接干预。