最代码伊成的gravatar头像
最代码伊成2018-01-02 10:08:04
记录一次oracle锁表排除经历

    背景:功能代码都写好了,进入测试阶段后,测试妹子测功能的时候,一切数据填入都是对的也没有发生异常的情况下,突然开发的接口提示504了。

    排查经过:用idea排查之后发现在某一段代码里面,该更新的数据sql貌似没有被执行,于是开始查看sql如下:

update
		A  ad
		set ad.status='1',
		ad.update_date=sysdate,
		ad.amount=#{Amount}
		where ad.code = #{Code}
		and ad.verify = #{verifyCode}

咋一看 这条sql是没有任何毛病的,放在PL-SQL里面也是可以执行的,那么就不是这个sql语句的问题,为了重现这个bug,于是叫测试重新测试一下。重新debug,开始怀疑没有执行这sql语句的原因是因为事物的缘故,后来才发现是因为 这条 sql 执行了但是一直在执行没有返回的结果,所以最后接口给出的504。

最后,猜测可能被锁表了,执行如下sql:

SELECT object_name, machine, s.sid, s.serial# 
FROM gv$locked_object l, dba_objects o, gv$session s 
WHERE l.object_id = o.object_id 
AND l.session_id = s.sid; 

tips:执行这条sql 需要oracle DBA的权限,否则无法执行

查询出如图:

记录一次oracle锁表排除经历

这就说明真的被锁了,执行如下sql,先把锁住的表释放掉:

ALTER system kill session '630, 15423';

这里的后面两个数据就是 查询出来对应的SID 和 SERIAL# 

到这一步,你觉得问题就解决了吗?

事实问题并没有解决掉,从代码层面看了一圈,我确定没有问题,那么我就去找测试,我说怎么操作出来的,看了半天,好像操作没什么问题,后来才知道,测试在测过程的时候,需要查询数据库某一个字段,然后填入,然后做功能测试,也就是这一个查询导致了死锁。他的sql语句如下:


select * from A for update;

那么问题就来了,for update是什么鬼?相信很多牛牛们都可能不是很熟悉这个,大家用mysql 可能查询就是直接写

select * from 某某表 

关于for update 是什么玩意看如下内容:

如果只是select 的话,Oracle是不会加任何锁的,也就是Oracle select 读到的数据不会有任何限制,虽然这时候有可能另外一个进程正在修改表中的数据,并且修改的结果可能影响到你目前select语句的结果,但是因为没有锁,所以select结果为当前时刻表中记录的状态。

 如果加入了for update Oracle一旦发现(符合查询条件的)这批数据正在被修改,则不会发出该select语句查询,直到数据被修改结束(被commit),马上自动执行这个select语句。

如图:

记录一次oracle锁表排除经历

 说到这,原因出来了。如果在查询的时候加了for update并且没有commit的时候,再其他程序跑这个update 语句的时候表会被锁住,导致你程序的时候sql 没有执行响应,所以在查询的时候,建议不要轻易使用 for update 

后面还有 oracle for update 和 for update nowait的知识扩展,就不继续多费笔墨了。

附上链接 有需要的可以自行学习查看:https://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html


打赏

已有1人打赏

最代码官方的gravatar头像

分享到:

最近浏览
苗毅66661月20日
最代码贡献等级说明
暂无贡献等级
byj19871月18日
暂无贡献等级
hugege1月16日
最代码贡献等级说明
8888887891月14日
暂无贡献等级
a10487331801月12日
暂无贡献等级
众口喂1月12日
暂无贡献等级
筱进GG LV31月12日
最代码贡献等级说明
夏虫123zzc1月11日
最代码贡献等级说明
zhizaideren1月11日
最代码贡献等级说明
135243862611月11日
暂无贡献等级
zyl1月11日
最代码贡献等级说明
murphyLu1月10日
最代码贡献等级说明
CQYlove1月10日
暂无贡献等级
明恋怡1月9日
最代码贡献等级说明
zuoai1月8日
暂无贡献等级
sevenvsky1月8日
最代码贡献等级说明
顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友