perl - 如何使用 Perl DBI 在 Oracle 中超时 "select for update"

标签 perl oracle dbi

有没有一种简单的方法可以让 SQL 语句超时,这样它就会失败而不是等待(例如,传递一个空的结果集或错误消息或其他任何东西),这样我就可以让作业的资源预订失败并给另一个机会?我正在寻找迄今为止我忽略的一些 DBI 选项;向自己发送 SIGALRM 以自杀并不是我的想法(尽管如果必须的话,我可能不得不诉诸于此)。

截取的代码是伪代码并缩短到了极点,但我希望你能捕获它。

my $sql = "SELECT one, two, three FROM sometable WHERE this = ? AND that = ?";
my $sth = $self->make_handle( $sql );
eval {
    foreach my $this ( sort keys %needed_ressources ) {
        # vvv This is where the idle time is spent vvv
        $sth->execute( $this, $that ) or die( "DB connection gone?!" );
        # ^^^ This is where the idle time is spent ^^^
        my ( $one, $two, $three ) = $sth->fetchrow_array();
        unless( $one ) { # undefined record set == not found
            $self->{DB_HANDLE}->rollback();
            die( "$this not defined for $that!" );
        }
    }
    # If we haven't died so far, we can move on
    foreach... #similar loop here doing the actual update statement
    $self->{DB_HANDLE}->commit();
};
return( 1 ) unless $@;
return( undef );

这里是有兴趣的血腥细节:

在执行大规模并行数字运算的应用程序中,有一个使用 oracle 表实现的资源锁定机制。每个作业需要锁定多个读取资源和/或写入多个资源,并且只有在成功获取所有锁后才能启动。与其耐心等待资源被释放,不如让作业失败并稍后由它们的主人重新运行(这样可以保持较低的未处理事务数量,同时通过在实际紧要关头有更多作业来提高性能)。

当然,在实际更新表之前,每行都使用“SELECT ... FOR UPDATE”语句保留,因此 Oracle 使用行级锁定,并发事务可以在表上发生。为了进一步减少可能的竞争条件和死锁,所有作业首先选择它们的资源行,然后在执行更新之前使用相同的顺序对它们进行行锁定。

就目前的实现而言,这在大多数的情况下都能正常工作。但是,因为在 Oracle 实际授予行锁之前“选择更新”会阻塞,因此可能仍然会发生作业空闲等待其资源的情况,而我正在寻找这些以更好地利用可用的 CPU 能力。等待一两秒钟是可以的,但不是十秒钟或更长时间只是为了锁定。对于un稍后锁定,当然需要等待,因此将整个数据库连接设置为只接受即时结果是行不通的。

我总是感谢 RTFM 的回答,只要他们指出 M 中我应该 TF 拥有 的位置>R ;-))

非常感谢您,
奥尔凡

最佳答案

我认为您需要 FOR UPDATE 子句中的 NOWAIT 参数。如果无法锁定记录,则选择将失败(“ORA-00054:资源繁忙并获取指定的NOWAIT”) 并且您可以根据需要处理异常。查看 SQL Reference manual .是 11g 的,但现在几个版本的语法没有改变。

另一种选择是给一个时间等待:“FOR UPDATE WAIT 3”等待 3 秒以获取锁,而不是立即失败。

关于perl - 如何使用 Perl DBI 在 Oracle 中超时 "select for update",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/966147/

相关文章:

perl - Perl中map或grep的使用

perl - 在 perl @ARGV 中查找管道和重定向

windows - 如何使用 Perl 在 Windows 中创建 unicode 文件名

从数据库中断中恢复的 Java DAL?

oracle - 如何获取 Oracle 的 SID 列表

Perl DBI - 使用多条语句运行 SQL 脚本

MySQL 乘法输出和 Perl DBI

perl - 使用 perl 连接到数据库

perl - 这个混淆的 Perl 是如何工作的?

java.sql.SQLSyntaxErrorException : ORA-01747