不太好理解的死锁

这几天做压力测试,数据库是ORACLE的,报了死锁的错误,错误信息是ORA-00060等待资源时检测到死锁。

分析了下程序的日志,大致情况是这样的,第一个线程成功锁住了两条记录(1,2),第二个线程需要锁四条记录(1,2,3,4),因为前面两条已经被第一个线程锁住,所以第二个线程进入等待,第三个线程需要锁两条记录(1,2),也进入等待,第四个线程需要锁两条记录(3,4),并且加锁成功。这里锁数据都是在事务内用SELECT * FROM TABLE_NAME WHERE CONDITION FOR UPDAT,也就是说都是TX锁。当第一个线程提交事务后,第二个线程就报了死锁的错误。

我们都知道,发生死锁的条件是两个线程各自锁住了另外一个线程需要的资源并且等待另外一个线程释放资源。而上面第二个线程之前一直都是等待的状态,所以不是很好理解。经过对trc文件的分析,得到的结论是,对于1,2两条记录,第二个线程和第三个线程,虽然sql都没有执行成功,但是各自锁了其中一条记录,并且等待另外一个线程释放另一条记录,从而导致了死锁的发生。

咨询了一个做DBA的朋友,这个可能和表的索引有关系,一个线程使用了主键索引,而另外一个线程则使用了普通的索引,经过对索引的调整,后面暂时没有报错,但是还是感觉比较奇怪,为什么不是同一批数据同时锁住。这个错误不是必发的,但概率还是比较高的。虽然索引经过了调整,但主键索引和普通索引还是都存在的,也就是说,只是降低了死锁发生的概率。

发表评论

电子邮件地址不会被公开。 必填项已用*标注