|
|
最初由 wyq21973 发布
[B]自治事务看不到调用事务未提交的更改,所以自治事务不能用在这种情况。
UPDATE我觉得倒不是大问题,只要不是索引组织表,因为在触发器中也能房问当前更改记录的rowid。 [/B]
这两句话都有问题。
触发器中的自治事务内看不到触发事务未提交的更改,也看不到其它事务未提交的更改。
用AFTER UPDATE触发器可以简单实现UPDATE后唯一性的检查。
我刚刚试了一下,用触发器维护同步表也做不出这个功能,在同一个会话内部可以,但不同会话间不行。
[php]
wyq@ORCL>create table t (id int);
Table created.
wyq@ORCL>create table t_mirror as select * from t;
Table created.
wyq@ORCL>create or replace trigger t_trg1
2 before insert or update or delete on t
3 for each row
4 Declare
5 l_Cnt Pls_Integer;
6 Cursor Cur_Cnt(p_Id Pls_Integer) Is
7 Select 1 From t_Mirror Where Id = p_Id For Update;
8 Begin
9 If Inserting Then
10 l_Cnt := 0;
11 For x In Cur_Cnt(:New.Id) Loop
12 l_Cnt := l_Cnt + 1;
13 End Loop;
14 If l_Cnt > 0 Then
15 Raise_Application_Error(-20011, 'duplicate id,insert denied!');
16 End If;
17
18 Insert Into t_Mirror Values (:New.Id);
19 End If;
20 If Updating Then
21 Update t_Mirror Set Id = :New.Id Where Id = :Old.Id;
22 End If;
23 If Deleting Then
24 Delete From t_Mirror Where Id = :Old.Id;
25 End If;
26 End;
27 /
Trigger created.
wyq@ORCL>insert into t values (1);
1 row created.
wyq@ORCL>insert into t values (2);
1 row created.
wyq@ORCL>select * from t;
ID
----------
1
2
wyq@ORCL>insert into t values (1);
insert into t values (1)
*
ERROR at line 1:
ORA-20011: duplicate id,insert denied!
ORA-06512: at "WYQ.T_TRG1", line 12
ORA-04088: error during execution of trigger 'WYQ.T_TRG1'
wyq@ORCL>
[/php]
上面演示了对这个表的串行插入可以检测到冲突ID,但当有多个会话并发进行插入时,检测不到可能有的冲突ID,游标的行锁没有效果,因为其它事务插入的相同数据如果还未提交就不可见。 |
|