Oracle for update [of column] | [nowait] 详解

文章目录

1 概述

  • 单独的 select 语句 是不会添加任何锁的
  • 可通过 for update 语句 锁住行数据 或 表数据

2 语法

select * from table_name for update [of column1, columnN][wait n|nowait];

 
 

语法解析:

1. 表级锁: 锁住表中所有的记录
	select * from table_name for update; -- 锁住表中所有的记录
	select * from table_name where column_name = 1 for update; -- 锁住表中列名为 1 的记录	
2. 行级锁: 锁住某列的记录(单表时,加不加效果一样。多表时,锁定 of column 列对应的表)
	select * from table_name for update of column1;
3. wait n | nowait
	(1) wait 5: 当锁冲突时,等待 5s 后报错(资源正忙...(2) nowait: 当锁冲突时,立即报错(资源正忙...
 
 

3 实例

3.1 for update of column

总体结论:

连接的表个数解释
单表for update 和 for update of 是一样的
多表只锁定 of column 对应的表(同一个表锁定一个列即可)

其它:

  • 不加 where 条件,是对全表进行锁定
  • 加了 where 条件 ,是对行级别的锁定

单表时:for update 和 for update of column 没区别

结论:session 2 中 dml 语句 都要等待 session 1 commit 或 rollback

请注意:
1.scott.emp 和 scott.dept 是 Oracle 内置的表,用于测试使用的
2.scott.emp 是数据表,scott.dept 是类型表(外键)

场景1:for update
session 1:

SELECT * FROM scott.dept t WHERE t.deptno = 10 FOR UPDATE;

 
 

session 2:

UPDATE scott.dept t SET t.loc = 'test_lock' WHERE t.deptno = 10;

 
 

场景2:for update of column
session 1:

SELECT * FROM scott.dept t WHERE t.deptno = 10 FOR UPDATE OF t.loc, t.dname; -- 仅多了 OF t.loc, t.dname

 
 

session 2:

UPDATE scott.dept t SET t.loc = 'test_lock' WHERE t.deptno = 10;

 
 

在这里插入图片描述


多表时:只锁定 of column 对应的表(同一个表锁定一个列即可)

结论:session 2、3 中的 dml 语句中 非 of column 列对应的表,无需等待 session 1 commit 或 rollback

场景1:for update
session 1:

SELECT e.empno, e.ename, d.deptno, d.dname
  FROM scott.emp e, scott.dept d
 WHERE d.deptno = e.deptno
   AND d.deptno = 10
   FOR UPDATE;

 
 

session 2:

UPDATE scott.emp e SET t.ename = 'test_ename' WHERE e.deptno = 10;

 
 

session 3:

UPDATE scott.dept d SET t.dname = 'test_dname' WHERE d.deptno = 10;

 
 

在这里插入图片描述

场景2:for update of column
session 1:

SELECT e.empno, e.ename, d.deptno, d.dname
  FROM scott.emp e, scott.dept d
 WHERE d.deptno = e.deptno
   AND d.deptno = 10
   FOR UPDATE OF d.dname; -- 仅多了 OF d.dname

 
 

session 2:

UPDATE scott.emp e SET t.ename = 'test_ename' WHERE e.deptno = 10;

 
 

session 3:

UPDATE scott.dept d SET t.dname = 'test_dname' WHERE d.deptno = 10;

 
 

在这里插入图片描述

3.2 wait n | nowait

结论:

  • wait 5: 当锁冲突时,等待 5s 后报错(资源正忙…)
  • nowait: 当锁冲突时,立即报错(资源正忙…)

session 1:

SELECT * FROM scott.dept t WHERE t.deptno = 10 FOR UPDATE;

 
 

session 2:

SELECT * FROM scott.dept t WHERE t.deptno = 10 FOR UPDATE NOWAIT;

 
 

在这里插入图片描述

4 扩展:rowid

1. 通过 for update 的方式修改表记录会产生 锁
	SELECT * FROM scott.dept t WHERE t.deptno = 10 FOR UPDATE;	
2. 通过 rowid 的方式修改表记录是不会产生 锁 的
	SELECT t.*, ROWID FROM scott.dept t WHERE t.deptno = 10;

 
 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值