1 oracle triggers transactions isolation-level
考虑一个包含3列的表:ID(唯一的,取自Oracle序列),CATEGORY和CODE(最后两个没有约束).
每个类别都附加了多个代码,但代码在该类别中必须是唯一的.例:
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //wrong
Run Code Online (Sandbox Code Playgroud)
第三个不行,因为我们已经为类别1提供了代码Y.
现在考虑在插入和检查之前运行的触发器,以查看要插入的值是否正常.也就是说,对于正在插入的记录,触发器读取类别,然后从表中读取具有该类别的所有代码,如果必须插入的记录中的代码已经存在,则引发异常以便记录没有插入.
我的问题是,如果事务隔离级别是,READ_COMMITED并且在两个不同的事务中几乎完全同时执行了两个插入但是事务稍后提交,那么触发器会在表中"看到"的内容是什么?
例:
(1)最初,表格如下所示:
ID CATEGORY CODE
1 1 X
Run Code Online (Sandbox Code Playgroud)
(2)T1和T2有两个事务(READ_COMMITED两者的隔离级别);
(3)两个交易都要插入category = 1和code = Y;
(4)T1执行插入并执行触发.表中没有Y所以可以插入;
(5)T2执行插入并执行触发.表中没有Y(T1尚未提交),因此可以插入;
(6)T1提交,表现在看起来像这样:
ID CATEGORY CODE
1 1 X
2 1 Y
Run Code Online (Sandbox Code Playgroud)
(7)T2现在提交.这里发生了什么?我是否收到错误并且未插入记录或我得到下表:
ID CATEGORY CODE
1 1 X
2 1 Y
3 1 Y //this is wrong
Run Code Online (Sandbox Code Playgroud)
?!
触发器"看到"什么以及插入物会发生什么?
不要使用触发器进行此类验证.触发器不会缩放.此外,您已经注意到它们无法在多用户环境中工作.这就是大自然赋予我们独特限制的原因.
alter table your_table
add constraint yr_tab_uk unique (category, code)
using index
/
Run Code Online (Sandbox Code Playgroud)