「SELECT~FOR UPDATE NOWAIT」

本文探讨了数据库中的阻塞现象,解释了如何通过SELECT FOR UPDATE NOWAIT等语句避免阻塞,并讨论了常见DML语句(如INSERT、UPDATE、DELETE等)在交互式应用中的阻塞问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阻塞

如果一个会话持有某个资源的锁,而另一个会话在请求这个资源,就会出现阻塞(blocking)。这样一来,请求的会话会被阻塞,它会“挂起”,直至持有锁的会话放弃锁定的资源。几乎在所有情况下,阻塞都是可以避免的。实际上,如果你真的发现会话在一个交互式应用中被阻塞,就说明很有可能同时存在着另一个bug,即丢失更新,只不过你可能没有意识到这一点。也就是说,你的应用逻辑有问题,这才是阻塞的根源。

数据库中有5条常见的DML语句可能会阻塞,具体是:INSERT、UPDATE、DELETE、MERGE和SELECT FOR UPDATE。对于一个阻塞的SELECT FOR UPDATE,解决方案很简单:只需增加NOWAIT子句,它就不会阻塞了。这样一来, 你的应用会向最终用户报告,这一行已经锁定。另外4条DML语句才有意思。我们会分别分析这些DML语句,看看它们为什么不应阻塞,如果真的阻塞了又该如何修正。


阻塞的MergeUpdateDelete

在一个交互式应用中,可以从数据库查询某个数据,允许最终用户处理这个数据,再把它“放回”到数据库中,此时如果UPDATE或DELETE阻塞,就说明你的代码中可能存在一个丢失更新问题(如果真是这样,按我的说法,就是你的代码中存在bug)。你试图UPDATE(更新)其他人正在更新的行(换句话说,有人已经锁住了这一行)。通过使用SELECT FOR UPDATE NOWAIT查询可以避免这个问题,这个查询能做到:

q  验证自从你查询数据之后数据未被修改(防止丢失更新)。

q  锁住行(防止UPDATE或DELETE被阻塞)。

如前所述,不论采用哪一种锁定方法都可以这样做。不论是悲观锁定还是乐观锁定都可以利用SELECT FOR UPDATE NOWAIT查询来验证行未被修改。悲观锁定会在用户有意修改数据那一刻使用这条语句。乐观锁定则在即将在数据库中更新数据时使用这条语句。这样不仅能解决应用中的阻塞问题,还可以修正数据完整性问题。

由于MERGE只是INSERT和UPDATE(如果在10g中采用改进的MERGE语法,还可以是DELETE),所以可以同时使用这两种技术。

该语句用来锁定特定的行(如果有where子句,就是满足where条件的那些行)。当这些行被锁定后,其他会话可以选择这些行,但不能更改或删除这些行,直到该语句的事务被commit语句或rollback语句结束为止。

摘自《 Oracle 9i & 10g编程艺术数据库体系结构 》
根据提供的引用内容,select for update是一种在Oracle数据库中使用的锁定机制,它可以锁定符合where条件的数据行,以防止其他事务对这些数据行进行修改。而select for update nowait则是在锁定数据行时,如果无法立即获取锁定,则会立即返回错误信息,而不是等待其他事务释放锁定。 相比之下,select for update insteal是一种更加灵活的锁定机制,它可以在不阻塞其他事务的情况下锁定数据行。当一个事务需要锁定某些数据行时,如果这些数据行没有被其他事务锁定,则该事务可以立即获取锁定并继续执行。如果这些数据行已经被其他事务锁定,则该事务会等待其他事务释放锁定,然后再获取锁定并继续执行。 以下是一个使用select for update insteal的示例: ```sql -- 假设有一个名为test的表,其中包含id和name两列 -- 现在需要锁定id为1的数据行,以便进行修改操作 -- 如果该数据行已经被其他事务锁定,则等待其他事务释放锁定后再进行锁定操作 -- 开启一个事务 BEGIN TRANSACTION; -- 锁定id为1的数据行 SELECT * FROM test WHERE id = 1 FOR UPDATE OF name NOWAIT; -- 如果上一条语句返回了错误信息,则表示无法立即获取锁定 -- 可以选择等待一段时间后再次尝试获取锁定,或者回滚事务并退出 -- 如果上一条语句没有返回错误信息,则表示已经成功获取锁定 -- 可以对该数据行进行修改操作 -- 提交事务 COMMIT; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值