最近在工作中,用Spring的Quartz处理数据,由于数据量过大,就基于一个时间戳处理,但在部署时部署两个instance时,就出现了漏处理数据的问题。
分析发现,取数过程是一个事务,由于数据量比较大,数据取完后就交给另个Service处理。进一步分析,取数前获得时间戳,数据查询后,再将记录的最后一条记录提时间戳更新回时间戳(当然,实现应用比这复杂),因为获取数据的查询语句加了for update skip locked,所以之前一直相信,即使是多个instance也不会出现漏处理数据。
后来进一步分析,发现确实就是对for update skip locked理解有误导致的。
测试过程如下:
create table bj_test(id number not null); insert into bj_test values(1); insert into bj_test values(2); insert into bj_test values(3); commit;
实验一:连续两次执行同一个如下SQL语句:
select * from bj_test where rownum <= 1 for update skip locked;
结果如下:
实验二:再开启另一个SESSION窗口执行,却发现没有查询出任何数据。
分析如下:
因为同一个SESSION的锁定可以重复获取,所以实验一的第二条语句仍然能查询出同样的数据。而对于实验二的结果,我再做一个测试,即在另一个SESSION窗口执行:select * from bj_test for update skip locked;如下:
可以发现后面两条记录并没有被第一个SESSION锁定。那为何 select * from t where rownum <= 1 for update skip locked; 这个就 no rows 呢?其实是因为 for update 执行情况我们误解了。对于存在 for update 的SQL语句,Oracle首先在没有for Update的情况下选取出满足条件的记录。然后对选取出的记录进行lock。如果后skip locked,那么在锁定记录的时候对于满足条件的记录中已经被锁定的将会再次被筛选掉。
如下是for update skip locked 的执行过程:第一个SESSION 中锁定了第一条记录(Rownum <=1 ), 第二个SESSION 中依然按照 (Rownum<=1) 取到第一条ID=1的记录,在后继执行for update skip locked 的时候发现记录被锁定,则被筛选掉,那么最终结果就是no rows了。
总结:skip locked 是在SQL查询结果集的基础上进行二次筛选。
另外,增加一个知识点:使用了 For Update 查询的表上会放置一个MODE=3 的TM锁定,而不管该查询是否查询到数据。
解决问题及本文资料来源:http://www.itpub.net/thread-1060874-1-1.html
相关推荐
SVN在客户端执行UPDATE报locked的处理办法,这里报错是提示工作拷贝“D:\svn_repository\cmout\cm\SVN\SVN客户端\TortoiseSVN\download”锁住了
锁相环经典书籍,对于想了解无线电,激光器锁相或许有帮助。
CD-Rom for the book "Phase-Locked Loops Design,Simulation and Applications by R.E.Best. A design program for Phase-locked loops circuits
解析oracle对select加锁的方法以及锁的查询一、oracle对select加锁方法 代码如下:create table...—session 1 模拟选中一个号码SQL> select * from test where a =1 for update skip locked; A B———- ———- 1
模拟集成电路的分析与设计:Chapter 15-Phase-Locked Loops.ppt
The fundamental design concepts for phase-locked loops implemented with integrated circuits are outlined. The necessary equations required to evaluate the basic loop performance are given in ...
解决sqlite死锁示例异常database is locked示例
stm32 flash解锁,我的是开发板,在按键中断中解锁flash,具体的见源代码,使用ram.icf,把程序烧录在ram中,环境是IAR6.10,库版本是3.0,成功解决Core is locked-up问题。~
pg队列 ...pg-queue使用SELECT FOR UPDATE SKIP LOCKED来获取maxProcessingConcurrency作业,这样就不会阻止并发工作程序 如果需要FIFO处理,则只需要一个消耗实例PgQueue和maxProcessingConcurrenc
Oracle; the account is locked
Very good code for Phase locked Loop in matlab
PHASE-LOCKED LOOPS FOR WIRELESS COMMUNICATIONS Digital, Analog and Optical Second Edition
这是一本介绍锁相环比较清楚的书籍。该书从模拟以及数字锁相环的角度进行分析,并介绍了在其他领域的应用。
Data converters, phase-locked loops, and their applicationsNdjountche, Tertulien"With a focus on designing and verifying analog integrated circuits, the book reviews design techniques for more complex...
Sqlite解决database locked问题
Oracle锁表常用sql语句: select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ...select * from tc_daily_quotation for update; select * from tc_Pre_Contract_Bail for update;
介绍RF仿真,可以用于微博专业同学学习之用。。。
JSSC 关于电荷泵锁相环的JSSC论文