使用 Perl DBI 的 SQL Server 事务问题

发布于 2024-10-18 17:18:12 字数 540 浏览 7 评论 0原文

我有以下代码块,其中 BEGIN TRAN< 内有 INSERTUPDATE 语句代码>END TRAN块。

现在我们都知道这个操作是原子的。但我的看法并非如此。由于违反唯一约束,插入失败,但更新仍然发生。当我直接在 SQL Server 中执行同一块时,我可以看到该操作是完全原子的。 PERL DBI 前端是否有任何内容覆盖了 BEGIN TRANCOMMIT TRAN。有什么指点吗?

$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 1;

我的$sql =“开始TRAN

         插入$表...

         更新$表....

         提交 TRAN”;
$dbh->do($sql);

I have the below code block with a INSERT and an UPDATE statement inside a BEGIN TRAN and END TRAN block.

Now we all know that this operation is atomic. But i am seeing otherwise. the insert fails due to a unique constraint violation , but still the UPDATE happens. When I execute the same piece in SQL server directly , i can see that the operation is perfectly atomic. Is there anything on the PERL DBI front which is overriding the BEGIN TRAN and COMMIT TRAN. Any Pointers ?

$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 1;

my $sql = "BEGIN  TRAN

         INSERT INTO $table ...

         UPDATE $table ....

         COMMIT TRAN";
$dbh->do($sql);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

慵挽 2024-10-25 17:18:12

我假设您正在使用 DBD::ODBC,因此当您阅读以下内容时请记住这一点。

默认情况下,DBI 将处于自动提交模式,除非您禁用它。

不要通过 do 方法将使用此类事务的多个 SQL 片段传递给 SQL Server,因为 DBD::ODBC 默认情况下将使用 SQLExecDirect 进行 do,并且 do 的设计并没有真正考虑到多个语句。您最好使用准备/执行或拆分 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 过程中。

I'm assuming you are using DBD::ODBC so bare this in mind when you read the following.

By default DBI will be in AutoCommit mode unless you disabled it.

Don't pass multiple pieces of SQL which uses transactions like this to SQL Server via the do method as DBD::ODBC will use SQLExecDirect for do by default and do is not really designed with multiple statements in mind. You are better using prepare/execute or splitting your SQL up and doing the commit in Perl like this:

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

or putting your insert/update in a SQL Server procedure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文