SKIP LOCKED 子句的使用
(2013-01-13 21:04:26)
标签:
oraclelock |
分类: 小记 |
程序中处理并发问题时,经常需要用 for update 字句来锁住将要处理的行,以免同一行数据被多个程序同时处理,而导致数据一致性出现问题。
但是for update有一个缺陷,就是将导致不必要的等待。
举例来说:
我们有一张事务处理表 my_transactions,其中有一列status,如果为1,则表示该行数据等待处理。
我们的程序开头可以写成这样:
selec * from my_transactions where status = 1 for update;
这样就将所有 status为1的数据锁定,如果同时有另一个相同的程序在运行,那么新的程序在刚开始运行时,就会阻塞在
selec * from my_transactions where status = 1 for update;
这条语句上。
到目前为止,听起来一切正常。
然而考虑稍微复杂一些的情况,假设my_transactions表中目前有1000条待处理的数据,
1.程序A1开始运行,1000条status=1的数据已经被锁定。
2.my_transactions表中新增了10000条status=1的数据等待处理。
3.相同的程序A2开始运行,但是当其刚开始运行至
问题出现了,虽然my_transactions表中有10000条待处理的新记录,A2却还是毫无必要地被A1阻塞。这样的阻塞是没有道理的。
那么如何既保证数据一致性不被破坏,同时又避免上述例子中的情况呢?
skip locked 特性就是为了这种场合而诞生的。
我们将
selec * from my_transactions where status = 1 for update;
改为
selec * from my_transactions where status = 1 for update skip locked;
回到之前的例子
1.程序A1开始运行,1000条status=1的数据已经全部被锁定。
2.my_transactions表中新增了10000条status=1的数据等待处理。
3.相同的程序A2开始运行,当其刚开始运行至
这样,我们既保证了数据一致性不被破坏,同时又避免了不必要的锁定等待。