Oracle select for update 用法

SELECT FOR UPDATE 用法

1、SELECT…FOR UPDATE 语法
SELECT … FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];
其中:
  OF 子句用于指定即将更新的列,即锁定行上的特定列。
  WAIT 子句指定等待其他用户释放锁的秒数,防止无限等待锁释放。

2、for update 作用
select for update 是为了在查询时,避免其他用户对该表进行插入、修改、删除等操作,用于保证表数据的一致性。
例如:
select * from zh_tb for update; 会等待行锁释放之后,返回查询结果。
select * from zh_tb for update nowait; 不等待行锁释放,提示锁冲突,不返回查询结果。
select * from zh_tb for update wait 5; 等待5秒,若行锁仍未释放,则提示锁冲突,不返回查询结果。
select * from zh_tb for update skip locked; 查询返回查询结果,忽略掉有行锁的记录。
注意:如果查询带条件那么只会锁定条件中的行数据,未带条件则会锁定表。

3、使用 FOR UPDATE WAIT 子句的优点
防止无限期地等待被锁定的行。
允许应用程序中对锁的等待时间进行更多的控制。
对于交互式应用程序非常有用,因为这些用户不能等待不确定。
若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告。

4、for update 用法
在Oracle中如果只是使用select的话,Oracle是不会给数据加锁的。当数据正在被另一个进程修改的时候,使用select得到的结果就不是最新的,这就需要使用for update,当oracle发现满足条件的记录正在被更新时,不会立即执行select语句,而是一直等待下去,直到更新结束才会执行select语句。

for update 用法举例:
会话1执行如下命令:
SQL> create table zh_tb(c1 varchar(20) ,c2 varchar(20));

Table created.

SQL> select * from zh_tb;

no rows selected

SQL> insert into zh_tb values ('ZZH','ZZH');

1 row created.

SQL> insert into zh_tb values ('AHERN','AHERN');

1 row created.

SQL> select * from zh_tb for update;

C1                   C2
-------------------- --------------------
ZZH                  ZZH
AHERN                AHERN

SQL> commit;

在会话2执行如下查询:
SQL> select * from zh_tb where c1='ZZH' for update;

C1                   C2
-------------------- --------------------
ZZH                  ZZH
此时会话2使用 for update 锁定了查询出来的记录:

再次在会话一执行如下语句查询所有记录:
SQL> select * from zh_tb for update;

发现无法查询出结果,并且会话一直处于等待状态,这是因为会话2里的语句锁住了C1='ZZH'的行,此时会话会一直处于等待状态。只有等会话2中提交了事务之后,会话1才能返回查询结果。
此时我们在会话2执行提交命令提交事务,会话1立即返回了查询结果如下:
SQL> commit;

Commit complete.

SQL> 
提交后发现会话1立即返回了查询结果如下:
SQL> select * from zh_tb for update;
... 

C1                   C2
-------------------- --------------------
ZZH                  ZZH
AHERN                AHERN

SQL> SQL> 

如果大家对 for uodate nowait、for update skip locked 和 for update wair n 用法感兴趣,可以采用如下语句在不同的会话中去执行验证它不同的锁定逻辑。
select * from zh_tb for update nowait;
select * from zh_tb for update wait 6;
select * from zh_tb where rownum<=3 for update skip locked;

5、使用场景
FOR UPDATE 适合可以等待其他事务释放锁定的场景,这样可以逐一处理数据行,确保数据的一致性。
FOR UPDATE NOWAIT 适合那些需要立即知道是否可以锁定所需行的场景,如果无法立即获得锁定,则可以迅速做出响应。
注意:选择使用FOR UPDATE还是FOR UPDATE NOWAIT取决于具体应用场景和对事务等待时间的容忍度。

FOR UPDATE NOWAIT 和 FOR UPDATE的区别:
两者的区别在于如果所选行已经被另一个事务锁定,FOR UPDATE NOWAIT 会立即引发一个 ORA-00054 错误,而不是一直等待其他事务释放锁。

### 回答1: Oracle中的SELECT FOR UPDATE语句用于锁定查询结果集中的行,以便在事务中进行更新操作。当一个事务使用SELECT FOR UPDATE语句锁定了某些行时,其他事务将无法对这些行进行更新操作,直到锁定的事务释放了锁。这种机制可以确保数据的一致性和完整性。 ### 回答2: Oracleselect for update 是一种锁定行功能,它可以确保在一个事务中,当一个会话开始更新数据时,另一个会话无法修改这些数据。 使用 select for update 首先需要使用 select 语句,该语句从需要更新的表中选择需要锁定的行。然后使用 for update 子句将这些行锁定。例如,下面是一个使用 select for update 的 SQL 语句: SELECT * FROM myTable WHERE id = 1 FOR UPDATE; 这个语句将检索 myTable 表中 id 为 1 的行,并将其锁定,以便其他会话无法修改此行,直到当前会话完成。 请注意,使用 select for update 会对数据库性能产生负面影响。由于锁定行后其他会话无法访问这些数据,因此可能会出现锁定竞争的情况,导致其他会话阻塞等待。因此,应谨慎使用 select for update,只在必要时使用它。同时还需要在程序中考虑一些优化思路,例如使用更细粒度的锁定,减少锁定时间等手段,以降低锁定导致的性能问题。 总之,select for updateOracle 中的一个很有用的功能,它可以确保数据的一致性和完整性。但是,在使用它时,需要仔细考虑并合理利用,以提高其性能效果。 ### 回答3: 在Oracle数据库中,SELECT ... FOR UPDATE语句用于锁定查询结果集中的行,以防止其他事务修改它们。在使用SELECT ... FOR UPDATE语句时,要在语句中明确地指定哪些列需要被锁定。如果不指定任何列,则默认会锁定所有列。 使用SELECT ... FOR UPDATE语句可以保证多个事务在并发修改同一行数据时不会发生冲突。这种锁定行的方式称为行级锁定。 SELECT ... FOR UPDATE语句可以与基于行级锁定的事务并发使用,并且可以充分利用Oracle数据库并发控制机制,提高系统的性能。 例子: 假设有一个账户表,在多个线程中需要对账户进行加款操作,需要保证加款时不会有其他线程同时进行减款操作。 可以使用以下SQL语句来实现这个功能: ```sql SELECT * FROM account WHERE account_number = '123456' FOR UPDATE; ``` 该语句会锁定account_number为"123456"的行,以防止其他事务修改该行数据。当一行被锁定时,其他事务不能修改该行。如果其他事务尝试修改该行,则会被阻塞,直到锁定被释放。 在加款操作完成后,需要手动提交事务或者回滚事务,以释放锁定。如果事务没有被提交或回滚,则锁定会一直存在,直到事务结束。 ```sql UPDATE account SET balance = balance + 100 WHERE account_number = '123456'; ``` 需要注意的是,使用SELECT ... FOR UPDATE语句时要小心死锁的问题。如果多个事务在查询同一行数据时都使用了FOR UPDATE语句,可能会出现死锁情况,这是需要谨慎处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ahern_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值