使用perl DBI的SQL server事务问题
我有下面的代码块,在使用perl DBI的SQL server事务问题,sql,sql-server,perl,transactions,dbi,Sql,Sql Server,Perl,Transactions,Dbi,我有下面的代码块,在开始传输和结束传输块中有一个插入和更新语句 现在我们都知道这个操作是原子的。但我看到的不是这样。由于唯一约束冲突,插入失败,但仍会进行更新。当我直接在SQLServer中执行同一部分时,我可以看到操作是完全原子化的。在perldbi前端是否有任何内容覆盖了BEGIN-TRAN和COMMIT-TRAN。有什么建议吗 我假设您使用的是DBD::ODBC,所以在阅读以下内容时,请记住这一点 默认情况下,DBI将处于自动提交模式,除非您禁用它 不要通过do方法将使用类似事务的多个SQ
开始传输和结束传输
块中有一个插入和更新语句
现在我们都知道这个操作是原子的。但我看到的不是这样。由于唯一约束冲突,插入失败,但仍会进行更新。当我直接在SQLServer中执行同一部分时,我可以看到操作是完全原子化的。在perldbi前端是否有任何内容覆盖了BEGIN-TRAN
和COMMIT-TRAN
。有什么建议吗
我假设您使用的是DBD::ODBC,所以在阅读以下内容时,请记住这一点
默认情况下,DBI将处于自动提交模式,除非您禁用它
不要通过do方法将使用类似事务的多个SQL片段传递给SQL Server,因为默认情况下DBD::ODBC将使用SQLExecDirect for do,do的设计实际上没有考虑多个语句。您最好使用prepare/execute或拆分SQL,然后用Perl进行提交,如下所示:
$dbh->{RaiseError} = 1;
$dbh->begin_work;
eval {
$dbh->do(q/insert.../);
$dbh->do(q/update.../);
$dbh->commit;
1;
};
if ($@) {
$dbh->rollback or warn "rollback failed";
}
或者将插入/更新放在SQL Server过程中。是的,我们使用DBD::ODBC-那么我们可以执行$dbh->{'AutoCommit'}=0?由于我们使用$dbh->do从perl代码调用所有查询,并且所有查询都在BEGIN TRAN和COMMIT TRAN块中,所以您可以尝试禁用AutoCommit,但我不确定它是否能够解决整个问题。在do中使用多个sql语句不是一个好主意。谢谢bohica-除了DBD::ODBC之外,还有其他驱动程序可以使用吗?这样我仍然可以使用$dbh->do($sql),其中$sql在BEGIN TRAN后面跟INSERT/UPDATE语句,后面跟END TRAN。如果这是DBD::ODBC的一个已知问题,那么任何其他库都可以解决我的问题并使事务仍然是原子的,而不必担心设置自动提交和每次执行提交?Hi Bohica-我尝试了->begin_work,它工作得非常好。我还有$dbh->prepare()语句,它们的BEGIN TRAN后跟INSERT/UPDATE语句,END TRAN后跟INSERT/UPDATE语句。现在,如果我对准备好的块执行$dbh->execute(),它会是原子的(即使发生约束冲突),还是容易出现$dbh->do()之类的问题
$dbh->{RaiseError} = 1;
$dbh->begin_work;
eval {
$dbh->do(q/insert.../);
$dbh->do(q/update.../);
$dbh->commit;
1;
};
if ($@) {
$dbh->rollback or warn "rollback failed";
}