У вас есть таблица, которая уже заблокирована.Это было объяснено по этой ссылке: https://community.oracle.com/thread/634676. Не одобряется указание только ссылки, поэтому я и здесь выложу ответ.
Поскольку какой-то другой сеанс имеет блокировку для этой таблицы, вы можете удалить ее, потому что фактически удаляете свое согласованное по чтению представление таблицы.См. Этот тестовый пример:
В сеансе 1:
YAS@10G>create table t as select * from dual;
Table created.
YAS@10G>insert into t values(2);
1 row created.
В сеансе 2:
YAS@10G>truncate table t;
truncate table t
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
YAS@10G>delete from t;
1 row deleted.
YAS@10G>commit;
Commit complete.
YAS@10G>select * from t;
не выбрано ни одной строки. Я не смог усечь его, так как сеанс 1вставил строку, и он держит замок на столе.Я мог удалить из таблицы, потому что строки, которые я хочу удалить, не заблокированы.
TRUNCATE - это DDL, и для него требуется эксклюзивная блокировка на столе.Сеанс 1 удерживает общую блокировку таблицы, которая не позволяет другому сеансу получить эксклюзивную блокировку.
Чтобы решить вашу проблему, вы можете просто повторить усечение при ошибке.
#!/usr/bin/perl
# your code goes here
use strict;
use warnings;
my $dbh = DBI->connect("dbi:Oracle:xxx","xxx","xxx", {RaiseError => 1});
my $sth=$dbh->prepare("TRUNCATE TABLE MONTHLY_DATA");
my $retryLimit = 5;
my $retrySleep = 5;
my $retryCount = 0;
$sth->execute()
|| &retry();
$dbh->disconnect();
sub retry {
sleep($retrySleep);
$retryCount++;
if ($retryCount le $retryLimit) {
print qq{Retrying the TRUNCATE of MONTHLY_DATA\n};
$sth=$dbh->prepare("TRUNCATE TABLE MONTHLY_DATA");
$sth->execute() || &retry();
return;
} else {
print qq{Retried TRUNCATING TABLE MONTHLY_DATA $retryLimit times. Quiting now\n};
exit;
}
}
Как правило, это будет работать вокруг вашей проблемы.Играя в игру ожидания.Если ваша таблица также всегда пишется, возможно, вам не удастся использовать ее с успехом.Затем я бы предложил заблокировать ваш стол и затем усечь.Другим предложением является создание таблицы, подобной этой таблице, затем замена их и удаление старой таблицы (я знаю, что вы можете сделать это в MySQL, не уверенный в Oracle).