我在多个会话中执行了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;
/
我仍然在表格中有重复的条目,这怎么可能发生?
答案 0 :(得分: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。
答案 1 :(得分:1)
如果您不想在表格中使用重复项,请使用UNIQUE CONSTRAINTS。