【问题标题】:Executing multiple SPs containing BEGIN TRANS - COMMIT TRANS using TransactionScope使用 TransactionScope 执行多个包含 BEGIN TRANS - COMMIT TRANS 的 SP
【发布时间】:2012-05-30 12:37:58
【问题描述】:

当 BEGIN TRANS - COMMIT TRANS 在一个 SP 中完成并在 TransactionScope 中执行多个 SP 并在完成范围之前引发错误时会发生什么。

所以伪代码如下

//Using TransactionScope() {
//   executing SP1 
//   executing SP2
//   executing SP3
//   throw new Exception();
//}

SP2 包含如下代码。

// BEGIN TRANS
//   Update Statement1
//   Update Statement2
//   Update Statement3
// COMMIT TRANS

如果我们假设事务在 SP2 中提交,会发生什么?

  1. 一切都会回滚
  2. SP2 中的 3 条语句被提交。其他所有内容都会回滚?

我不知道这是否重要,但以防万一,所有三个 SP 都使用一个连接对象执行,并且连接在两个 ExecuteNonQuery 语句之间关闭并再次打开。

【问题讨论】:

  • 如果任何一个 SP 发生错误,事务将被回滚。如果 SP2 被提交,但 SP3 抛出错误,则不会发生更新,整个事务将回滚。
  • @praveen 你为什么不把它作为答案发布?
  • 那是我的错误。无论如何,如果我的回答对你有任何帮助,我会更高兴

标签: sql-server sql-server-2008 transactions transactionscope


【解决方案1】:

只有一个事务,总是由最外层事务范围开始的最外层事务。所有其他内部事务范围和 T-SQL 代码中发生在最外层事务范围下的所有其他 BEGIN TRANSACTION 只不过是 @@TRANCOUNT 的美化增量,所有这些 COMMITS 只不过是相同的减量。只有最后一次 COMMIT 才重要,直到那时事务还没有提交。

因此,在您的示例中,SP2 没有提交任何内容。它所做的一切都是将@@TRANCOUNT 增加到 2,然后将其减少回 1。事务仍然处于活动状态,并且当 C# 代码抛出时,事务将回滚。

作为附注,请参阅Exception handling and nested transactions,了解如何编写良好的异常安全存储过程的模板。

【讨论】:

  • 它已经被接受了,然后我不接受它,以便其他打算回答的人也可以发布答案或投票给你的答案。否则其他人可能会认为它已回答并且他们不需要访问它。我仍然会等待其他人对您的答案进行投票,然后在一两天内接受它。不过,看看你的声誉,我相信你至少不会提供错误/误导性的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 2014-01-18
相关资源
最近更新 更多