1

我在多个会话中执行了以下 PL/SQL:

DECLARE
   x     NUMBER;
   y     NUMBER;
BEGIN
   x := 500;
   y := 0;
   WHILE (x > y)
   LOOP
       SET TRANSACTION 

       Select max(SERIAL_NO) INTO y from MY_TABLE;

       y := y + 1;

       insert into MY_TABLE S (S.SERIAL_NO, S.Request_id)
       values ((
                (select max(SERIAL_NO) from MY_TABLE) + 1
               )
              ,'B');

       Commit;

   END LOOP;
END;
/

我的表中仍然有重复的条目,这怎么会发生?

4

2 回答 2

4

当然。Oracle 具有已提交的事务隔离级别。

例如,如果两个会话像这样运行:

Time  Session A                                 Session B
1     (Select max(SERIAL_NO) from MY_TABLE)+1
2                                               (Select max(SERIAL_NO) from MY_TABLE)+1
3     commit;

您将在表中获得 SERIAL_NO 的重复项,因为会话 A + B 看到 SERIAL_NO 的值相同。

您需要使用序列来确保唯一性(或实现您自己的信号量风格 - 但我不推荐这样做)。

您的SET TRANSACTION陈述缺少一些参数,但这无论如何都无济于事(如果您想到的话SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

另请参阅http://docs.oracle.com/cd/B19306_01/server.102/b14220/consist.htm#sthref1981关于可串行化隔离事务级别和数据并发性和一般一致性的内容。

于 2012-07-23T06:35:22.057 回答
1

如果您不想在表中出现重复项,请使用 UNIQUE CONSTRAINTS。

于 2012-07-23T06:33:16.287 回答