从 Dblib 到 DBI 的 Sybase 事务更新

Transactional updates to Sybase from Dblib to DBI

我目前有一个 perl 代码,它通过 Sybase::DBlib 连接到 Sybase 并执行以下操作

$dbh->sql('Begin tran');
$query= <some delete query>
$dbh->sql($query)
in a loop{
    do insert query
}
COMPLETE:
$dbh->sql('commit tran');

我正在移植上面的代码以开始使用 DBI,但我不确定如何处理事务。如何使用 DBI 模拟上述内容。 COMPLETE 是做什么的?

是。

看看TRANSACTIONS in the DBI docs。它给出了这个代码示例。

$dbh->{AutoCommit} = 0;  # enable transactions, if possible
$dbh->{RaiseError} = 1;
eval {
    foo(...)        # do lots of work here
    bar(...)        # including inserts
    baz(...)        # and updates
    $dbh->commit;   # commit the changes if we get this far
};
if ($@) {
    warn "Transaction aborted because $@";
    # now rollback to undo the incomplete changes
    # but do it in an eval{} as it may also fail
    eval { $dbh->rollback };
    # add other application on-error-clean-up code here
}

对于您的特定 use-case,您可以这样做:

$dbh->{AutoCommit} = 0;
$dbh->{RaiseError} = 1;
eval {
    $dbh->prepare("DELETE FROM stuff");
    $dbh->execute;
    $dbh->commit;
};
if ($@) {
    warn "Transaction aborted because $@";
    eval { $dbh->rollback };
}

最重要的部分是您需要在开始交易之前关闭AutoCommit自己。这只需更改 $dbh.

的内部结构即可

请注意,您也可以使用 Try::Tiny 代替 eval 块,这样看起来更好一些。

如果您想重新打开 auto-committing 以便不再有交易,只需设置 $dbh->{AutoCommit} = 1


你也可以在1使用begin_work and commit and leave $dbh->{AutoCommit},这样你就不用乱用了。

use Try::Tiny;

try {
    $dbh->begin_work;
    $dbh->do( ... );
    $dbh->commit;
catch {
    warn "Transactino aborted because $_";
    try { $dbh->rollback };
};