Sybase从Dblib到DBI的事务更新

时间:2017-02-08 12:41:04

标签: perl sybase 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做了什么?

1 个答案:

答案 0 :(得分:1)

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

<add name="MigrateDBFaktura3Entities"
           connectionString="metadata=res://*/DB.ServerData.csdl|res://*/DB.ServerData.ssdl|res://*/DB.ServerData.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=FASTEC-ATTEST\SQLEXPRESS;initial catalog=MigrateDBFaktura5;persist security info=True;user id=**;password=**;MultipleActiveResultSets=True;App=EntityFramework&quot;"
           providerName="System.Data.EntityClient" />

对于您的具体用例,您可以这样做:

$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
}

最重要的是,在开始交易之前,您需要自行关闭AutoCommit 。只需更改$dbh->{AutoCommit} = 0; $dbh->{RaiseError} = 1; eval { $dbh->prepare("DELETE FROM stuff"); $dbh->execute; $dbh->commit; }; if ($@) { warn "Transaction aborted because $@"; eval { $dbh->rollback }; } 的内部即可。

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

如果您想重新启用自动提交,以便不再有任何交易,只需设置eval

您还可以使用begin_workcommit并将$dbh->{AutoCommit}留在$dbh->{AutoCommit} = 1,这样您就不必惹它了。

1