Oracle 的for update行锁

本文详细介绍了Oracle数据库中SELECT...FOR UPDATE语句的使用方法及其子句的功能,包括OF、WAIT、NOWAIT和SKIP LOCKED等子句,并通过示例展示了不同子句的应用效果。

关键字: oracle 的for update行锁

  SELECT...FOR UPDATE 语句的语法如下: 
  SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED]; 
其中: 
  OF 子句用于指定即将更新的列,即锁定行上的特定列。 
  WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。 
  “使用FOR UPDATE WAIT”子句的优点如下: 
  1防止无限期地等待被锁定的行; 
  2允许应用程序中对锁的等待时间进行更多的控制。 
  3对于交互式应用程序非常有用,因为这些用户不能等待不确定 
  4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告 

示例: 
create table t(a varchar2(20),b varchar2(20)); 
insert into t values('1','1'); 
insert into t values('2','2'); 
insert into t values('3','3'); 
insert into t values('4','4'); 
现在执行如下操作: 
在plsql develope中打开两个sql窗口, 
在1窗口中运行sql 
select * from t where a='1' for update; 
在2窗口中运行sql1 
1. select * from t where a='1'; 这一点问题也没有,因为行级锁不会影响纯粹的select语句 
再运行sql2 
2. select * from t where a='1' for update; 则这一句sql在执行时,永远处于等待状态,除非窗口1中sql被提交或回滚。 
如何才能让sql2不等待或等待指定的时间呢? 我们再运行sql3 
3. select * from t where a='1' for update nowait; 则在执行此sql时,直接报资源忙的异常。 
若执行 select * from t where a='1' for update wait 6; 则在等待6秒后,报 资源忙的异常。 
如果我们执行sql4 
4. select * from t where a='1' for update nowait skip Locked; 则执行sql时,即不等待,也不报资源忙异常。 
现在我们看看执行如下操作将会发生什么呢? 
在窗口1中执行: 
select * from t where rownum<=3 nowait skip Locked; 
在窗口2中执行: 
select * from t where rownum<=6 nowait skip Locked; 
select for update 也就如此了吧,insert、update、delete操作默认加行级锁,其原理和操作与select for update并无两样。 
select for update of,这个of子句在牵连到多个表时,具有较大作用,如不使用of指定锁定的表的列,则所有表的相关行均被锁定,若在of中指定了需修改的列,则只有与这些列相关的表的行才会被锁定。

 
 

<think>我们被要求解释OracleFOR UPDATE的作用,并参考了站内引用[1][2][3][4]。根据这些引用,我们可以总结如下: 1. FOR UPDATE用于在SELECT语句中定选中的,以防止其他会话同时修改这些(引用[1][2][3])。 2. 在没有使用FOR UPDATE的情况下,SELECT语句不会加,因此可能读取到其他事务尚未提交的修改(脏读)或者读取过程中数据被修改导致不一致(引用[1])。 3. FOR UPDATE会使得当前事务一直等待,直到获得所需(引用[1])。 4. 会在事务提交或回滚时自动释放(引用[2])。 5. 使用FOR UPDATE可以确保数据的一致性和隔离性(引用[2][3])。 6. 引用[3]提供了示例代码,展示如何在一个事务中使用FOR UPDATE定一,然后更新该,最后提交事务。 7. 引用[4]提到了数据库链接,但似乎与FOR UPDATE的作用关系不大。 因此,我们可以这样回答用户: 在Oracle数据库中,FOR UPDATE子句用于在SELECT查询时定所选的,以实现数据的一致性和隔离性。具体作用包括: - 定查询结果集中的,防止其他事务并发修改这些。 - 确保当前事务在修改这些之前,其他事务不能修改它们,从而避免脏读和不可重复读等问题。 - 当使用FOR UPDATE时,如果目标已被其他事务定,则当前事务会等待直到被释放(除非使用了NOWAIT选项)。 例如,在一个事务中: ```sql SELECT * FROM employees WHERE employee_id = 1 FOR UPDATE; UPDATE employees SET salary = 5500 WHERE employee_id = 1; COMMIT; ``` 上面的代码先定employee_id为1的,然后更新该,最后提交。在定后,其他事务尝试更新同一时会被阻塞,直到当前事务提交。 的释放发生在事务提交(COMMIT)或回滚(ROLLBACK)时。 相关问题: 1. FOR UPDATE和SELECT ... FOR UPDATE NOWAIT有什么区别? 2. 在哪些场景下应该使用FOR UPDATE? 3. 使用FOR UPDATE时如何避免死? 4. FOR UPDATE是否会影响查询性能? </think>### Oracle 中 `FOR UPDATE` 的作用详解 在 Oracle 数据库中,`FOR UPDATE` 是 `SELECT` 语句中的一个关键子句,主要用于**实现定**,其核心作用体现在以下方面: 1. **定机制** - 当执 `SELECT ... FOR UPDATE` 时,Oracle 会对查询结果集涉及的**自动施加级排他(Row Exclusive Lock)**。 - 例如: ```sql SELECT * FROM employees WHERE employee_id = 1 FOR UPDATE; -- 定 employee_id=1 的 [^3] ``` - 被定的**禁止其他事务修改或删除**(但允许读取),确保定期间数据不被并发修改[^2][^3]。 2. **保证数据一致性** - 在事务中先定目标再修改,可避免脏读和不可重复读问题。例如: ```sql BEGIN SELECT salary INTO v_salary FROM employees WHERE employee_id=1 FOR UPDATE; -- UPDATE employees SET salary = v_salary * 1.1 WHERE employee_id=1; -- 安全修改 COMMIT; -- 提交后释放 END; ``` 该过程确保 `salary` 在读取和更新之间不会被其他事务修改[^1][^3]。 3. **事务隔离性控制** - 默认情况下,如果目标已被其他事务定,当前事务会**阻塞等待**直到释放(可通过 `NOWAIT` 改为立即报错): ```sql SELECT * FROM orders WHERE order_id=100 FOR UPDATE NOWAIT; -- 不等待直接报错 ``` 这有效防止了长时间定等待[^1][^2]。 4. **释放条件** 在以下情况自动释放: - 事务提交(`COMMIT`) - 事务回滚(`ROLLBACK`) - 会话终止[^2][^3]。 --- ### 典型应用场景 1. **悲观并发控制** 在需要先查询后更新的业务中(如库存扣减、账户转账),通过 `FOR UPDATE` 定数据防止覆盖冲突。 2. **数据完整性维护** 对关键数据(如订单状态)执原子操作时,确保中间状态不被干扰。 3. **跨会话协调** 在分布式系统中同步对共享资源的访问[^1][^3]。 > ⚠️ 注意:过度使用 `FOR UPDATE` 可能导致死或性能下降,应配合短事务设计使用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值