今天早上过来时,发现公司的ETL采集任务中有个任务报错 错误信息是 ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源...(后面是指出过程PA报错)
看到这个错误,立马来精神了,这段时间学了oracle正好派上用场,我也来分析分析。首先打开了过程PA,发现在过程里调用了一个表T,而这个TB是正常的表,在另外一个采集任务(过程PB)中也是调用了这个表。而且两个任务对这个表的处理方式不一样。在PA的任务中,是truncate table T,而在PB的任务中,是delete B ...。一个是DDL操作,一个是DML操作,如果同时发生了,是不是就产生那样的错误。果然,上网查了一下,忘了是哪个老师的书上说了,如果是dml操作期间,执行了truncate,(即delete T 还未commit时,便执行了truncate table T),则会报ORA-00054错误。
以上只是推测,自己动手实践才是真理。开启一个会话,执行了delete T,再在同一个会话中,执行了truncate table T,奇怪了,这怎么就通过了,而且清空了表数据。想了想,应该是在两个不同的会话操作,才会出现错误的提示,试了一把,果然出现00054错误。
验证了错误,又看了下报错时间,以及PB的运行时间,差不多,两个在同一时间,应该就是这个问题了。立马把PA中的Truncate table T改成了delete table T。
改了之后,想想还是觉得这样的设计,其实是有问题的,说不准两个任务谁先谁后,所以这样不仅存在着锁的问题,而且存在数据准确性的问题。所以又把这两个任务中delete表时,添加了条件,让对方不能互相删除数据。