我目前有一个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
做了什么?
答案 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="data source=FASTEC-ATTEST\SQLEXPRESS;initial catalog=MigrateDBFaktura5;persist security info=True;user id=**;password=**;MultipleActiveResultSets=True;App=EntityFramework"" 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_work
和commit
并将$dbh->{AutoCommit}
留在$dbh->{AutoCommit} = 1
,这样您就不必惹它了。
1