【问题标题】:Are triggers executed with the current transaction isolation level?触发器是否以当前事务隔离级别执行?
【发布时间】:2009-08-31 09:26:07
【问题描述】:

考虑一个包含 3 列的表:ID(唯一,取自 Oracle 序列)、CATEGORY 和 CODE(对最后两列没有限制)。

每个类别都有多个代码,但代码在该类别中必须是唯一的。示例:

ID    CATEGORY   CODE
1     1          X
2     1          Y
3     1          Y     //wrong

第三个不行,因为我们已经有了类别 1 的代码 Y。

现在考虑一个在插入之前运行的触发器,并检查要插入的值是否正常。也就是说,对于正在插入的记录,触发器读取类别,然后从表中读取具有该类别的所有代码,如果必须插入的记录中的代码已经存在,则引发异常,以便记录没有插入。

我的问题是,如果事务隔离级别为READ_COMMITED,并且几乎完全相同的时间在两个不同事务中执行了两个插入但事务稍后提交,那么触发器将在表中“看到”什么?

例子:

(1) 最初,表格如下所示:

ID    CATEGORY   CODE
1     1          X

(2) 有两个事务 T1 和 T2(两者的隔离级别 READ_COMMITED);

(3) 两个事务都想插入类别 = 1 和代码 = Y;

(4) T1 执行插入并执行触发器。表中没有Y,可以插入;

(5) T2 执行插入并执行触发器。表中没有Y(T1还没有提交)所以可以插入;

(6) T1 提交,表格现在如下所示:

ID    CATEGORY   CODE
1     1          X
2     1          Y

(7) T2 现在提交。这里会发生什么?是出现错误且未插入记录还是得到下表:

ID    CATEGORY   CODE
1     1          X
2     1          Y
3     1          Y     //this is wrong

?!

触发器“看到”什么以及插入会发生什么?

【问题讨论】:

    标签: oracle transactions triggers isolation-level


    【解决方案1】:

    请勿使用触发器进行此类验证。触发器不会扩展。此外,正如您所注意到的,它们不适用于多用户环境。这就是为什么大自然给了我们独特的约束。

    alter table your_table
        add constraint yr_tab_uk unique (category, code)
        using index
    /
    

    【讨论】:

    • +1:尽可能使用约束而不是触发器。无论如何,在这种情况下,触发器将无法查询基表,因为这会引发 MUTATION 错误 (ORA-4091)。
    • @APC 嘿,我也有类似的问题,唯一的区别是对于某个类别,只允许一个 Y,而允许多个 X 出现,在这种情况下,unique不合适。
    • @JerryChin - 听起来像是一个完全不同的场景,您需要提出一个新问题。请务必包含涵盖您拥有的所有州的示例数据。
    猜你喜欢
    • 2011-03-26
    • 2011-09-30
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-27
    相关资源
    最近更新 更多