关于延迟约束

很多时候都只知道用约束来限制某些数据以完成业务逻辑,但在实际中发现也有应用延迟约束的场景.

场景如下:

库存表使用商品ID作为唯一标志,但在某一个时刻,即进入某个ID的商品卖完之后,再进入这个商品,(业务逻辑的处理),即可能在某个事务中短暂的存在两个相同的商品ID的情况.

此时我们就要应用到延迟唯一约束了.

实验如下:

–测试表

[sql]

  1. 11:33:43 SCOTT@orcl> DESC T02
  2.  名称                                                  是否为空? 类型
  3.  —————————————————– ——– ———————————-
  4.  ID                                                             NUMBER
  5.  SAL                                                            NUMBER
  6. 11:35:23 SCOTT@orcl> SELECT * FROM T02;
  7.         ID        SAL
  8. ———- ———-
  9.          1       1000
  10.          2       2000
  11.          3       6000
  12.          4       1000
  13.          5       2000
  14.          6       6000
  15. 已选择6行。
  16. 已用时间:  00: 00: 00.01

–实验(延迟验证,事务提交时验证)

[sql]

  1. 11:37:18 SCOTT@orcl> ALTER TABLE T02 ADD constraint con_uni_id UNIQUE (ID) INITIALLY DEFERRED;
  2. 表已更改。
  3. 已用时间:  00: 00: 00.56
  4. 11:37:46 SCOTT@orcl> insert into t02 select 5,2152 from dual;
  5. 已创建 1 行。
  6. 已用时间:  00: 00: 00.03
  7. 11:38:13 SCOTT@orcl> select * from t02 where id=5;
  8.         ID        SAL
  9. ———- ———-
  10.          5       2152
  11.          5       2000
  12. 已选择2行。
  13. 已用时间:  00: 00: 00.03
  14. 11:38:30 SCOTT@orcl> commit;
  15. commit
  16. *
  17. 第 1 行出现错误:
  18. ORA-02091: 事务处理已回退
  19. ORA-00001: 违反唯一约束条件 (SCOTT.CON_UNI_ID)
  20. 已用时间:  00: 00: 00.04

 

–立即验证(默认,也就是不加INITIALLY immediate也采用这种验证方式)

[sql]

  1. 11:38:35 SCOTT@orcl> ALTER TABLE T02 drop constraint con_uni_id;
  2. 表已更改。
  3. 已用时间:  00: 00: 00.06
  4. 11:40:56 SCOTT@orcl> ALTER TABLE T02 ADD constraint con_uni_id UNIQUE (ID) INITIALLY immediate;
  5. 表已更改。
  6. 已用时间:  00: 00: 00.07
  7. 11:41:36 SCOTT@orcl> insert into t02 select 5,2152 from dual;
  8. insert into t02 select 5,2152 from dual
  9. *
  10. 第 1 行出现错误:
  11. ORA-00001: 违反唯一约束条件 (SCOTT.CON_UNI_ID)
  12. 已用时间:  00: 00: 00.01

标签