2010-12-21 105 views
2

我将一行插入ORACLE数据库表中,其中 主键ID是自动增量。 和 我正在从该表重试自动增量的ID。在Oracle数据库中获取正确的自动增加的ID

在许多人使用相同的表的情况下。 我可能会遇到消费者生产者问题,我可能会在其中获得其他用户的ID号码为 。

一些用户对SO提到有关获取这些递增ID 是基于connection,不会在消费者生产者造成 问题:

只是想检查下面的事情与SO:

第一:

我会得到确切的自动递增ID从下面sceneario:

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 :) 

回答

4

您应该使用返回条款:

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这是正确的。

+0

对不起回复迟到。我想你正在谈论存储过程。但是我不能在DataBase Side中改变任何东西 – vrbilgi 2011-01-03 10:21:59

2

首先,没有像“自动增量”ID这样的生物。 Oracle具有序列和触发器。可以使用触发器在插入时选择序列值。 Oracle不保证顺序生成顺序,但不保证这些值没有差距。它确实保证你会得到一个独特的价值。所以实际上没有查询会告诉你最后一个序列被添加到表中。 MAX可能是正确的,但是从序列的缓冲区中拔出一个较低的数字,并在插入之前延迟,然后在较高的数字之后出现。

克雷格有正确的做法的最佳答案。剩下的是讨论你的四种情况。

您需要详细阅读ACID

ACID(原子性,一致性,隔离 ,耐用性)是一组 性质保证数据库 事务被可靠地处理。

鉴于您的代码可能具有并发性问题(即竞争条件或非线程安全),数据库不存在此类问题。 (不应该,通常也不会)良好的数据库从头开始设计以满足ACID的需求。每笔交易都与每笔交易隔离开来。如果您插入该表并在同一个交易中选择最大(ID),然后我插入该表并选择MAX(ID)作为我的一笔交易的一部分,我将看到插入的号码,您将看到插入的号码。任何给定的交易将只显示交易开始时存在的数据。

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

在设计不佳的数据库中,隔离是通过锁定完成的。如果您阅读了一行并保持事务处于打开状态,为了确保您的下一次阅读是相同的,您要求的行被锁定。这意味着读者可以阻止作家 - 这是一件坏事。在Oracle中,从版本5或版本6开始,Oracle可以通过MultiVersion Concurrency Control重新创建表中数据的视图,因为它在交易开始时显示。这已经是甲骨文20年来的默认行为。并非每个数据库都是如此先进......确保在数据库中执行任何操作之前,了解您正在使用的隔离级别。

相关问题