繁体   English   中英

在Oracle DB中获取正确的自动递增ID

[英]Getting correct auto incremented ID in Oracle DB

我正在ORACLE数据库表中插入一行,其中主键ID是自动增量。 我正在从该表中检索自动递增的ID。

如果许多人使用相同的表。 我可能会遇到消费者生产者问题,在那里我可能会获得其他用户的ID。

在SO上提到的有关获取这些递增ID的一些用户是基于连接的 ,这不会导致Consumer Producer问题:

只想用SO检查以下内容:

第一:

我会从以下场景中获取确切的自动递增ID:

1) Two computer with in different subnet using DB.
2) Two computer wiht in same subnet using DB.
3) Two process using using DB connection.
4) Two thread uisng DB connection.

第二

 If my insert is:
 Insert into Tables (ID,NAME,DESCRIPTION) values (DBNull,'Name','Description');

 What should be my query to get the autoincremented ID generated for above
 Insert.

C# related command will do much help :)

您应该使用returning子句:

declare
    v_id TABLES.ID%TYPE;
begin
    Insert into Tables (ID,NAME,DESCRIPTION)
    values (seq.nextval,'Name','Description')
    RETURNING id INTO v_id;
--
    dbms_output.put_line(v_id);
end; 

这样,您可以获得实际插入的ID,而不必重新查询最高的ID并希望它是正确的ID。

首先,不存在诸如“自动递增” ID的生物。 Oracle具有序列和触发器。 插入时,可以使用触发器来选择序列值。 Oracle不保证序列生成中的顺序,也不保证值之间没有间隔。 它确实保证您将获得独特的价值。 因此,实际上没有查询可以告诉您最后一个序列添加到表中的内容。 MAX可能是正确的,但是从序列缓冲区中抽出并在插入之前延迟的较低数字可能会在较高数字之后出现。

克雷格(Craig)为正确的方法提供了最佳答案。 剩下的就是对四种情况的讨论。

您需要阅读ACID

ACID(原子性,一致性,隔离性,持久性)是一组属性,可确保可靠地处理数据库事务。

尽管您的代码可能存在并发问题(即竞争条件或非线程安全的),但数据库没有此类问题。 (不应该,通常也不应该)良好的数据库是从头开始设计的,可以满足ACID的需求。 每个事务都与其他每个事务隔离。 如果您插入该表并在同一笔交易中选择Max(ID),而我插入该表并选择MAX(ID)作为我的一项交易的一部分,那么我会看到我插入的号码,并且会看到插入的号码。 任何给定的事务将仅显示事务开始时已存在的数据。

您可以通过更改隔离级别来覆盖此功能,但是ACID是一件好事。 你要这个。 Oracle长期以来一直像这样工作。

在设计不良的数据库中,隔离是通过锁完成的。 如果您读取一行并保持事务打开,则为了确保您的下一次读取相同,您要查询的行将被锁定。 这意味着读者可以阻止作家-这是一件坏事。 在Oracle中,从版本5或版本6开始,Oracle能够通过MultiVersion Concurrency Control重新创建表中的数据视图,该视图显示在事务开始时。 大约20年来,这一直是Oracle中的默认行为。 并非每个数据库都如此先进...在对数据库执行任何操作之前,请确保您了解要使用的隔离级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM