背景
我在代码中,用多线程去操作数据库,执行如下语句:
select * from table where rownum<10 for update;
然后进程程序跑着跑着就卡死了,也不知道什么原因,不知道为什么hi锁死,命名我在PLSQL控制台都可以完美的锁住的。
分析
我们知道,卡死的原因肯定是数据库死锁了,但是为什么会死锁呢,我在PLSQL先做了如下的操作:
1、线程A执行如下语句
select * from table where a=1 for update;
成功
2、线程B执行如下语句
select * from table where a=2 for update;
成功
3、线程A执行如下语句
select * from table where a=2 for update;
等待
4、线程B执行如下语句
select * from table where a=1 for update;
死锁!
惊了,这里竟然弹出了死锁,那么有理由分析上面的背景案例如下的操作:
select * from table where rownum<10 for update;
应该是ORACLE数据库对每一行多加锁,这个是有先后顺序的,然后另一个线程也对相同的行加锁,也有先后顺序,触发了上面的情况,然后就死锁了。
当然这个只是推测分析:Oracle对多行加锁不可能同时发生,因为机器执行是有时间顺序的。
总结:尽量不要for update多条记录。