嵌套存储过程中事务之间的关系?
我把交易放在我所有的“设定”程序中。没问题。一切正常。
在这种情况下,我需要一个设定的过程,谢天谢地,只调用另一个过程一次,否则可能会让事情变得更加复杂。
所以快乐的沐浴就是这样。
- 我在 ProcA 中并开始交易。
- 它调用 ProcB 并启动一个事务。
- ProcB 成功并提交。
- ProcA 成功并提交。
但是,如果 ProcB 失败、回滚并重新抛出错误,会发生什么情况。它应该也会导致 ProcA 回滚,对吗?
如果 ProcB 成功并提交,然后 ProcA 随后失败并回滚怎么办……ProcB 中发生的事情会回滚吗?或者它是否已承诺?
我需要这两者一起工作,要么都成功,要么失败并且都回滚。确保这种情况发生的最佳方法是什么?
我正在使用 Microsoft SQL Server 2008 R2 (SP1)
注意:如果 ProcB 需要事务,因为可以在没有 ProcA 包装它的情况下调用它。从技术上讲,ProcA 并不总是调用 ProcB(取决于输入)。
I put transactions in all my "set" procedures. No problems. Everything works.
In this case, I need one set procedure, to call another, thankfully, only once, or that would potentially complicate things further.
So the happy bath would be.
- I'm in ProcA and start a transaction.
- It calls ProcB and it starts a transaction.
- ProcB is successful and commits.
- ProcA is successful and commits.
However, what happens if ProcB fails, rollsback, and rethrows the error. It should cause ProcA to rollback as well correct?
What if ProcB succeeds, commits, then ProcA subsequently fails, and rollsback...will what happened in ProcB be rolled back? or is it commited?
I need these two to work together, either both succeed, or fail and both be rolled back. What's the best way to ensure this happens?
I'm working with Microsoft SQL Server 2008 R2 (SP1)
Note: If ProcB requires a transaction because it can be called without ProcA wrapping it. And technically, ProcA won't always call ProcB (depends on input).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
下面是一个简单的演示,展示了嵌套事务会发生什么:
如果您执行了 COMMIT TRANSACTION,而不是上面的 ROLLBACK,则实际上除了递减 @@TRANCOUNT 之外什么也不做。因此,您需要提交外部事务(这会将两行都提交到表中),或者执行 ROLLBACK ,这将导致没有行提交到表中。
以下是有关嵌套事务的 MSDN 参考: http://msdn.microsoft.com/en -us/library/ms189336.aspx
Here's a simple demo to show what happens with nested transations:
Instead f the ROLLBACK above, if you did a COMMIT TRANSACTION, this actual does nothing other then decrement @@TRANCOUNT. So you then would need to to either COMMIT the outer transaction (which would COMMIT both rows to the table), or do a ROLLBACK which would result in no rows being committed to the table.
Here's the MSDN ref on nested transactions: http://msdn.microsoft.com/en-us/library/ms189336.aspx
只需使用 XACT_ABORT ON 即可。运行以下脚本并亲自查看:
Just use XACT_ABORT ON, and you are all set. Run the following script and see for yourself:
我对事务很偏执(有一次该事务在生产中处于打开状态,半小时内没有人注意到......)所以我会像这样扭曲潜在内部事务:
所有事务处理(以及处理事务中发生的错误)必须在启动事务的任何级别进行处理。
(还有其他人注意到 BOL 实际上并没有说明当您向非最外层事务的指定事务发出 ROLLBACK 时会发生什么吗?他们确实阐明了所有其他排列......)
I'm paranoid about transactions (there was this transaction left open on Production once that no one noticed for half an hour...) so I'd warp the potentially inner transaction like so:
All transaction processing (and handling of errors that occur within the transaction) must then be dealt with at whatever level launched the transaction.
(And did anyone else notice how BOL doesn't actually say what happens when you issue a ROLLBACK to a named transaction that isn't the outermost transaction? They do spell out every other permutation...)